关于C语言中结构体字节对齐问题(2)

同理,分析上面例子C:
#pragma pack (2) /*指定按2字节对齐*/
struct C {
    char b;
    int a;
    short c;
};
#pragma pack () /*取消指定对齐,恢复缺省对齐*/
第一个变量b的自身对齐值为1,指定对齐值为2,所以,其有效对齐值为1,假设C从0x0000开始,那么b存放在0x0000,符合0x0000%1= 0;第二个变量,自身对齐值为4,指定对齐值为2,所以有效对齐值为2,所以顺序存放在0x0002、0x0003、0x0004、0x0005四个连续 字节中,符合0x0002%2=0。第三个变量c的自身对齐值为2,所以有效对齐值为2,顺序存放
在0x0006、0x0007中,符合0x0006%2=0。所以从0x0000到0x00007共八字节存放的是C的变量。又C的自身对齐值为4,所以 C的有效对齐值为2。又8%2=0,C只占用0x0000到0x0007的八个字节。所以sizeof(struct C)=8.

有 了以上的解释,相信你对C语言的字节对齐概念应该有了清楚的认识了吧。在网络程序中,掌握这个概念可是很重要的喔,在不同平台之间(比如在Windows 和Linux之间)传递2进制流(比如结构体),那么在这两个平台间必须要定义相同的对齐方式,不然莫名其妙的出了一些错,可是很难排查的哦^_^。

根据上面的解释,个人对参考文章1作如下总结:

struct S {
   int i;   // size 4
   short j;   // size 2
   double k;   // size 8
};

#pragma pack(2)
struct T {
   int i;
   short j;
   double k;
};

int main() {
   printf("%d ", offsetof(S, i));
   printf("%d ", offsetof(S, j));
   printf("%d\n", offsetof(S, k));

T tt;
   printf("%d ", offsetof(T, i));
   printf("%d ", offsetof(T, j));
   printf("%d\n", offsetof(T, k));
}struct S中,i的偏移量为0毋庸置疑,j的对齐值为2,但是由于i的对齐值占用了4个字节,所以由于4%2=0,所以对j而言,起始对齐位置是上文所说的自然位置,所以j的起始对齐位置为4,而对于k,由于前两个成员的总和偏移仅仅为4+2=6,而6%8!=0,所以必须在j后,k前填两个0(当然,视编译器不同而异),达到8位,使8%8=0,所以K的起始对齐位置为8,所以输出结果为:0,4,8;

第二个例子我就不多讲解了,因为原理相似,只是将默认对齐位置强制变为2而已。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/7e25c4c41f05ed51015217502ee3427b.html