结构体
结构体的自引用
-
结构体内部首先是不能进行自引用的。
-
如果需要,可以定义一个结构体的指针,这个指针指向自己。
struct Node { int data; struct Node* next; };
结构体内存对齐
规则
- 第一个成员在与结构体变量偏移量为0的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
对齐数=编译器默认的一个对齐数与该成员大小的较小值。
vs中默认的值为8 - 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
- 如果嵌套了结构体,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
为什么存在内存对齐?
-
平台原因:不是所有硬件平台都能访问任意地址上的任意数据的。
-
性能原因:对齐访问一次,不对齐处理器需要两次内存访问。
总体来说:结构体的内存对齐就是拿空间来换取时间的做法,因此在设计结构体的时候,我们既要满足对齐,又要节省空间 ,最好是让占用空间小的成员尽量集中在一起,不如从占用空间的从小到大排列,除此之外有些程序中我们也可以通过修改默认对齐数来减少空间的浪费
。#pragma pack()//取消默认对齐数,还原默认对齐数 #pragma pack(4)//设置默认对齐数为4
位段
位段的声明和结构体的声明类似,但有以下两点不同:
-
位段的成员必须是int、unsigned int 或signed int。
-
位段的成员名后边有一个冒号和一个数字。数字代表的是该成员占用几个位。
struct A { int _a:2; int _b:5; int _c:10; int _d:30; }; int main() { printf("%d\n", sizeof(struct A));//8 return 0; }
分析:
一个int类型的变量具有4个字节,32个比特位,2+5+10<32,因此abc放在一起,d单独放在一个int中,因此,一共使用了2个int,8个字节。
排列方法参考这个,这是小端机