一、结构体
1、结构体类型声明
struct tag //见名知义,可以省略但不建议省略
{
member_list; //C语言中不能为空
}variable_list; //建议省略
例如描述一个学生
struct Stu
{
char name[20];
int age;
char sex[5];
char id[20];
};
2、结构体初始化
struct Point
{
int x;
int y;
}p1;
struct Point p2;
struct Point p3 = {1, 2};
3、内存对齐
对齐的原因:
对齐的规则:
(1)第一个成员在与结构体变量偏移量为0的地址处。
(2)其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。VS默认值为8,Linux默认值为4。
(3)结构体的总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
(4)如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
4、结构体传参
结构体传参的时候尽量不要传结构体变量,要传结构体的指针。
原因:函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,会导致性能下降。
5、位段
(1)位段的成员可以是int,unsigned int,signed int,char类型。
(2)位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式开辟的。
(3)位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。
位段的声明:
struct MyStruct
{
int a : 2;
int b : 3;
char c : 3;
};
二、枚举
1、枚举的声明:{}中的内容是枚举类型的可能取值,也叫枚举常量。这些可能取值都是有值得,默认从0开始,一次递增1,也可以在定义的时候赋初值。
enum Color
{
RED = 1,
GREEN = 2,
BULE = 3,
};
枚举的优点:
(1)增加代码的可读性和可维护性。
(2)和#define定义的标识符相比枚举有类型检查,更加严谨。
(3)防止命名污染(封装)。
(4)便于调试。
(5)使用方便,一次可以定义多个常量。
三、联合
1、联合定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。所有的成员都可以看做是第一个元素。
union MyUnion
{
char c;
int i;
}un;
int main()
{
printf("%d\n",sizeof(un)); //结果为4
system("pause");
return 0;
}
2、联合大小的计算。
(1)联合的大小至少是最大成员的大小。
(2)当最大成员的大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
3、利用联合的巧妙使用判断CPU的大小端。
union MyUnion
{
char c ;
int i;
};
int main()
{
union MyUnion un;
un.i = 1;
printf("%d\n",un.c); //结果是1为小端,是0则为大端
system("pause");
return 0;
}