一、定义:
- 结构体是一些值的集合,这些值成为它的成员。结构体既是一种自定义类型,也是一种聚合数据类型。
这里我们谈到了聚合数据类型
所谓聚合数据类型,即就是同时存储超过一个的单独数据(如C中的数组和结构体)
二、结构体的声明
- 结构体在声明的时候必须要列出它包含的所有成员。
- 特殊举例:
struct S
{
char a;
char b;
int c;
}y[10],*z;
上述结构体的声明是合法的。
该结构体声明创建了一个包含了10个结构的数组y和一个指向该结构体类型的指针z
- 此外,结构体不仅可以在声明的时候同时定义变量,也可以先声明,后定义。如下:
struct S
{
char a;
char b;
int c;
};
struct S y[10],*z;
- 如果在多个源文件中使用同一个结构体,可以巧妙的运用typedef在头文件中声明,需要的源文件将其包含进来即可。
三、结构体的初始化及访问
- 结构体不能在声明的时候初始化。
struct S
{
char a;
int b;
int arr[4];
}x = { 'b', 2, { 1, 2, 3, 4 } };
- 直接访问:通过操作符“.”访问。格式为:结构体变量.需要访问的成员名(如:S.a)
- 间接访问:通过操作符“–>”来访问。
四、结构体的内存对齐
1.为什么要内存对齐?
平台原因(移植原因)
不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则会剖出硬件异常。
性能原因
数据结构(尤其是栈)应该尽可能的在自然边界上对齐。因为为了访问未对齐的内存,处理器需要做两次内存访问,而对齐的内存仅需要访问一次。
2.结构体内存对齐规则:
- 结构体变量的第一个成员永远都放在偏移量为0的地址处。
其他成员变量要对齐到对齐数的整数倍的地址处。
对齐数 = 编辑器默认的对齐数 与 该成员大小的较小值
VS默认对齐数为8、Linux默认对齐数为4
结构体总大小为最大对齐数的整数倍(每一个成员变量除了第一个成员都有一个对齐数)。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整数倍大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
注意:
1.结构体的默认对齐数是可以改的,使用#pragma pack(K)就可以设置对齐数。
2.一个空结构体的大小为一个字节
3.offsetof(A,a) ,其中A是一个结构体变量,a是一个成员
举个例子:
- 结构体中嵌套结构体的 内存对齐