结构体大小计算遵循两条规则:
1. 结构体大小成员的偏移量必须都是成员大小的整数倍(0被认为任何数的整数倍)
2. 结构体大小必须是所有成员(数组、结构体除外)大小的整数倍
ps:对齐方式很浪费空间,可是按照计算机得访问规则,这种对齐方式提升了效率
(1)普通结构体1
struct S1 //24
{
char ch1; //1 偏移值:0 char大小为1,0是任何整数的整数倍
char ch2; //1 偏移值:1
int i; //2+4 偏移值:2
float f; //4 偏移值:8
double d; //8 偏移值:16 16是8的整数倍,无需更改偏移值 总: 8+16=24
};
(2)普通结构体2
struct S2 //12
{
char ch1; //1
int i; //4+3 偏移量1不是int大小的整数倍,故偏移量加3,得3+4
char ch2; //1 偏移量为2是char大小的整数倍,不用增加偏移量 1+4+3+1=9不等于所有成员大小的整数倍,故结构体大小为12
};
(3)结构体含数组
struct S3 //20
{
char ch; //1
int i; //3+4
char str[10]; //10 10+1+3+4=18--->20 首先整数倍关系将数组抛开不算,18不是int大小4的整数倍,因此取20
//这里将str[10]改成str[12]结构体大小还是20,因为结构体大小整数倍关系数组要除外
};
(4)结构体包含结构体
struct S4 //32
{
char ch; //1
int i; //3+4
struct S //16
{
char ch1; //1
int n; //3+4
double p; //8
}; //不管是否定义了结构体变量都要将该结构体大小算进去,当然不同编译器存在差异,这里就按照把结构体S大小算进去计算
float f; //4 8+16+4=28---->32
};
ps:其中未定义的结构体变量是否算不算进去整个结构体大小需要根据不同编译器而定,因为不同编译器有差异,在VScode Mwing编译器下就不区分结构体变量是否定义没有,都要将结构体所中包含的结构体大小算进去。
/*struct SS
{
char ch;
int n;
}temp;*node*/ //定义的结构体变量temp,指针*node,这时的结构体大小就要考虑其整数倍关系了
(5)结构体包含联合体
struct S5 //12
{
char ch; //1
int i; //3+4
union
{
char ch1; //1
int n; //4+3
double d; //8
}; //1+3+4 + 4=12 --->联合体的大小按其内部成员最大大小来算
};
(6)pragma pack(4)向4对齐
#pragma pack(4) //指定向4对齐 最大是8 --->当成员大小超过pack括号里要求的值,则按照括号的值来对齐
struct S6 //20
{
char ch; //1
int i; //3+4
float f; //4
double d; //8 8+8+4=20
};
ps:这里的d的偏移量是12不是8的整数倍,因为向4对齐,故只需保证偏移量与结构体大小是4的整数倍即可(我的初浅的理解是这样的,如果不对还请指出,因为按照规则1,d的偏移量应该为16才对),当然如何去掉#pragma pack(4)
S6的大小就为24,即(1+3+4+4+4+8=24),其中d的偏移量为16。
(7)pragma pack(10)向10对齐
#pragma pack(10) //指定向10对齐 最大是8 --->当成员大小未超过pack括号里要求的值,则按照结构体内最大的值来对齐
struct S7 //24
{
char ch; //1
int i; //3+4
float f; //4
double d; //8 8+8+4=20
};
ps:d的偏移量与S6同理