计算结构体大小的计算不是简单的成员变量相加,要谨记两个原则:
1.每一个成员的偏移量都必须是该成员的倍数。(数组、结构体除外)
2.结构体的大小必须是所有成员大小的倍数。 (数组、结构体除外)
- 下面结构体中变量大小相加为6,但按照上面的第一个原则,实际上大小为8;
struct s1{
char ch1;
char ch2;
int i; //8
}s1;
- 遵循1,2原则s2大小为12
struct s2{
char ch1;
int i;
char ch2; //12
}s2;
- 结构体中存在数组,下面例子数组偏移量为1+4+3,数组和结构体没有原则束缚,所以直接加起来大小为22,为满足第二原则,大小为28,但第二原则数组和结构体除外,所以为24;
struct s3{
char ch;
int i;
char str[14]; //24
}s3;
- 结构体中的结构体,如果里面的结构体未实例化,则相当于没空间,不考虑,下例结构体大小为12
struct s4{
char ch;
int i;
struct s{
char ch1;
int j;
};
float f; //12
}s4;
- 结构体中的结构体,里面的结构体已实例化所以要算入其大小,可计算里面结构体为12,按照1,2原则(数组,结构体都不用满足1,2原则),大小为24
struct s5{
char ch;
int i;
struct s{
char ch1;
int j;
int k;
}temp;
float f; //24
}s5;
- 结构体中嵌套联合体,联合体只算最大的成员变量,所以结构体大小为12
struct s6{
char ch;
int i;
union{
char ch1;
int j;
}; // 12
}s6; //联合体大小为联合体中最大的变量
7. 对偏移量做了限定,如果结构体中有成员变量超过了限定大小,那么按限定大小执行。
下例如果没有限定,那么按照1,2原则可知结构体大小为24,但限定了大小且有成员变量超过了其限定大小,所以按限定大小执行,大小为20
#pragma pack(4)
struct s7{
char ch;
int i;
float f;
double d; //20
}s7;
8. 对偏移量做了限定,如果结构体中没有成员变量超过限定大小,那么按原计划执行,不做限定(相当于没有限定的那句语句)
如下图,大小为24
#pragma pack(10)
struct s8{
char ch;
int i;
float f;
double d; //24
}s8;
总结:结构体大小这种对齐方式虽然很浪费空间,但是按照计算机的访问规则,这种对齐方式提升了效率。