C语言字节对齐

参考自: 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;
}
原文地址:https://www.cnblogs.com/talenth/p/6830329.html