一、C语言与c++中的不同之:输入与输出
C++中既可以使用C语言中的输入输出函数也可以用Cin和Cout进行输入与输出,不需要格式控制。
# include<iostream> using namespace std; int main() { printf("hello world\n"); cout << "change world" << endl; return 0; }
(1)endl代表换行(也可以使用\n换行)
(2)需要包含输入输出流的头文件# include<iostream>
(3)需要在开头加入using namespace std;如果不加入,编译器会识别不了,采用以下方式,即加入命名空间即使不加入也可以识别:
# include<iostream> //using namespace std; int main() { printf("hello world\n"); std::cout << "change world" <<std:: endl; return 0; }
也可以将cout和endl引入标准空间来改正消除这个错误:
# include<iostream> //using namespace std; using std::cout; using std::endl; int main() { printf("hello world\n"); cout << "change world" <<endl; return 0; }
(4)、C语言中需要给出格式化的部分,c++中则不需要给出格式化的部分(输出浮点型等都直接给出值即可)
# include<iostream> using namespace std; int main() { printf("%d %c %lf", 1, '1', 1.0); cout << 1<<" "<<'1'<<" "<<1.0<<endl; //等同于 /*cout << 1 << endl; cout << '1' << endl; cout << 1.0<< endl;*/ return 0; }在C语言的格式化部分若是出现错误,会影响其他的格式化部分都出现错误。
printf函数返回值为成功输出字符的个数
scanf传的参数是不定的,最开始为格式化部分。若是给定接收的参数没有初始化 ,编译器会认为未初始化不安全,产生错误。如下:
int main() { int a, b; scanf("%d,%d",a, b); system("pause"); return 0; }
初始化后继续执行会异常中断,因为要传地址
int main() { int a=0, b=0; scanf("%d,%d",&a, &b); system("pause"); return 0; }
scanf的返回值为成功输入的参数个数
在C++中使用cin,cout
从控制台顺着输入输出流流入参数中:cin>>a;cout>>b。而且不需要关注其类型。
二、C语言中结构体的认识:
1、什么是结构体?
结构体是一系列数据的集合,这些数据可能描述了一个物体,也可能是对一个问题的抽象。
2、一般在什么情况下需要用到结构体?
(1)内置类型已经无法满足实际需求;
(2)参数打包:参数过多,一个一个的传递不方便,把参数打包在一块;
3、什么是内存对齐?为什么要内存对齐?怎样对齐?
在C语言中,若是没有重定义,必须用stuct 结构体名 实参名 来定义实参。而在c++中在可以用 结构体名 实参名 来定义实参而不需要加struct。
内存对齐”应该是编译器的“管辖范围”。编译器为程序中的每个“数据单元”安排在适当的位置上。但是C语言的一个特点就是太灵活,太强大,它允许你干预“内存对齐”。如果你想了解更加底层的秘密,“内存对齐”对你就不应该再透明了。对于内存对齐问题,主要存在于struct和union等复合结构在内存中的分布情况,许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们要求这些数据的首地址的值是某个数M(通常是4或8);对于内存对齐,主要是为了提高程序的性能,数据结构,特别是栈,应尽可能在自然边界上对齐,经过对齐后,cpu的内存访问速度大大提升。
Windows中默认对齐数为8,Linux中默认对齐数为4;
为什么要内存对齐:内存对齐的原因
(1、平台原因(移植原因)
A 不是所有的硬件平台都能访问任意地址上的任意数据的;
B 原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
对齐规则:1、结构体中每个成员 2、结构体整体
(1)第一个成员在与结构体变量偏移量为0的地址处。(在一个对齐的位置上)
(2)其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值,min(对齐参数,sizeof(成员))。VS中默认的值为8,gcc中的默认值为4
(3)结构体总大小为最大对齐数(每个成员变量除了第一个成员都有一个对齐数)的整数倍。min(对齐参数,类型最大成员所占字节数)
(4)如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
4、对齐参数如何设置?可以设置为按照任意字节对齐吗?
法1、
# pragma pack(对齐数)
#pragma pack()//恢复
法2、项目---》属性---》c/c++----》代码生成---》设置结构成员对齐数,更改默认设置:此方法一旦实现,整个工程的对齐数都将发生更改。
对齐参数不能任意设置,只能是内置类型已有的字节数,如:char(1)、short(2),int(4),double(8)…不能是3,5…任意数。
5、如何知道结构体中某个成员相对于结构体起始位置的偏移量?
宏offsetof可以求出结构体中某个成员相对于结构体起始位置的偏移量。
#pragma pack(4) struct A { int a; char b; double c; char d; }; #pragma pack() int main() { A a; cout << offsetof(A, c) << endl; cout << sizeof(A) << endl; return 0; }
实现一个宏(offsetof)或者函数实现结构体中某个成员相对于结构体起始位置的偏移量:
6、变长的结构体:
(1)intfo和其他的结构成员在同一块空间,info的空间可以为0,通过malloc申请需要的空间大小
struct student { char _name[20]; int _age; char _gender; int _len; char _info[0];//柔性数组 };(2)info与其他的结构体成员不在同一块空间,最小为4个字节,因为char *字符指针占4个字节。
struct student { char _name[20]; int _age; char _gender; int _len; char* _info; };
7、位段,联合体
8、大小端问题?如何来测试大小端(多种方式)?
大小端:
测试方式:
9、C语言与c++中结构体的相同和不同之处:
(1)定义实体的方式不同;
(2)初始化结构体的成员:C语言中一般用一个函数进行初始化,不可以将函数写道结构体里面(结构体里面不可以放函数);而在c++中结构体里面可以放函数。
结构体的一个实例:
struct student { char _name[20]; int _age; char _gender[3]; void SetInfo(char *name, int age, char *gender) { strcpy(_name, name); _age = age; strcpy(_gender, gender); } void PrintStudent() { cout << _name << " " << _age << " " << _gender << endl; } }; int main() { student s1, s2; s1.SetInfo("将旧", 28, "女"); s2.SetInfo("卡卡", 3, "男"); s1.PrintStudent(); s2.PrintStudent(); return 0; }