参考自: https://www.cnblogs.com/sunbines/p/9257981.html
一 字节对齐的原因
用空间换速度
二 字节对齐的原则
【原则1】数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。
【原则2】结构(或联合)的整体长度对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。
【原则3】结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小与#pragma pack指定的数值的较小值 的整数倍地址开始存储。(这个其实是对原则1的补充)
备注:
1 数组成员的长度按数组类型长度计算,如char t[9],在第1步中数据自身长度按1算,累加结构体时长度为9;第2步中,找最大数据长度时,如果结构体T有复杂类型成员A,该A成员的长度为该复杂类型成员A的最大成员长度。
2 对齐位数跟处理器位数和编译器都有关)VS, VC等编译器默认是#pragma pack(8), 注意gcc默认是#pragma pack(4),并且gcc只支持1,2,4对齐
3. 改变缺省的对齐长度:
-
- 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。
- 使用伪指令#pragma pack(),取消自定义字节对齐方式。
三 例子
1 #pragma pack(4) 2 struct BBBBB 3 { 4 char e; //[0] 5 short h; //[2,3] 6 7 struct A // 从[4]开始 8 { 9 char a; //[4] 10 double b; //[8,15] 11 char c; //[16] 12 }vvv; // A 长度补齐到20字节长度 即[19] 13 char bbb; //[20] 14 };// 结构补齐到24个字节长度 15 #pragma pack() 16 17 int main(void) 18 { 19 printf("%u ", sizeof(BBBBB)); //24 20 system("pause"); 21 return 0; 22 }
#pragma pack(8) struct BBBBB { char e; //[0] short h; //[2,3] struct A //从8开始 { char a; //[8] double b; //[16,23] char c; //[24] }vvv; //长度补齐到32字节, 即[31] char bbb; //[32] }; //长度补齐到40字节 #pragma pack() int main(void) { printf("%u ", sizeof(BBBBB)); //40 system("pause"); return 0; }