目录
前言
结构体存在内存对齐,所以对于不了对齐的是很难计算结构体的大小
1.结构体内存对齐
1.1规则
1.2举列
#include<stdio.h>
struct S1
{
char a;
int i;
char b;
};
struct S2
{
char a;
char b;
int i;
};
int main()
{
struct S1 s1;
struct S2 s2;
printf("%d\n", sizeof(s1));
printf("%d\n", sizeof(s2));
return 0;
}
在VS编译器下,明明变量内容是一样的,为什么算出的结果不相同
这是因为结构体的对齐
在VS编译器下,默认对齐数是8
假设从s1在内存中是从我画的地方开始的,对于根据规则,从我画的地址开始,所以a在
最初的位置,也就 我画的0处,然后是int i,因为int 字节是4,在VS环境下与8比较4比较小所以对齐数是4,放的位置就应该在4的倍数处,所以放在橙色处,占是四个字节, 然后是char b ,占一个字节与8比比较所以他的对齐数位1,接着放,然后根据,结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍 , 找到结构体中最大的是4,所以结果是4 的倍数,但是根据画图有9个byte,所以就是12byte。
同理对于s2,
因为,要从0偏移量开始,所以a在,红色区域,然后算b,8小于b的字节数(1),所以对齐数是1,就从这里开始,b在黄色区域,然后int, 4 < 8,所以对齐数是4,i的位置应该是4偏移量的倍数,也就是从4 开始,在s2中,最大对齐数是4,所以结果应该是4,的倍数,刚好就是8
1.3 结构体嵌套求大小
如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
根据规则可以知道,最大对齐是俩个中最大对齐数也就是8,(上面写在结构体旁边的就是 该的字节大小),刚好我们算出来的结果就是32,是8 的倍数,所以成立
1.4为什么存在内存对齐
用法总结 如果我们既要满足对齐,又要节省空间
1.5 修改默认对齐数
#pragma pack(1)//设置默认对齐数为1
struct S2
{
char c1;
int i;
char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{
//输出的结果是什么?
printf("%d\n", sizeof(struct S2));
return 0;
}
在这里我设置为了1,就是所说相当于没有对齐数,直接开始,这个我就不画图了,自己画,在这里结果就是6(在这里最大对齐数是1,看不太懂请看最前面规则)
1.6 结构体传参
结论:
结构体传参的时候,要传结构体的地址。
2.位端
位段的声明和结构是类似的,有两个不同:
内存分配
位段的跨平台问题
3.联合(共用体)
联合类型的定义
//联合类型的声明
union Un
{
char c;
int i;
};
int main()
{
//联合变量的定义
union Un un;
//计算连个变量的大小
printf("%d\n", sizeof(un));
}
修改i ,就等于修改了,c, 公用的是从起始位开始的。
特点
联合体计算
在这里算大小也是需要对齐的 ,
Un2同理就不讲解了
注意
修改联合体的公共部分是一同修改的