c语言字节强制对齐,C语言的那些小秘密之字节对齐

为了让读者加深印象,我们这里在代码中没有使用0,而是使用的4,所以在最终计算出的结果部分减去了一个4才是偏移地址,当然实际使用中我们都是用的是0。

懂了上面的宏offsetof之后我们再来看看下面的代码:

#include 

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

typedefstructstu1

{

inta;

charb[1];

intc;

}stu1;

voidmain()

{

printf("offsetof(stu1,a):\t%d\n",offsetof(stu1,a));

printf("offsetof(stu1,b):\t%d\n",offsetof(stu1,b));

printf("offsetof(stu1,c):\t%d\n",offsetof(stu1,c));

printf("sizeof(stu1)    :\t%d\n",sizeof(stu1));

}

运行结果为:

8b61b0fddc997d08fdd2149409bef95a.gif

offsetof(stu1,a):       0

offsetof(stu1,b):       4

offsetof(stu1,c):       8

sizeof(stu1)    :       12

Press any key tocontinue

对于字节对齐不了解的读者可能有疑惑的是c的偏移量怎么会是8和结构体的大小怎么会是12呢?因该是sizeof(int)+sizeof(char)+sizeof(int)=9。其实这是编译器对变量存储的一个特殊处理。为了提高CPU的存储速度,编译器对一些变量的起始地址做了对齐处理。在默认情况下,编译器规定各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数。现在来分析下上面的代码,如果我们假定a的起始地址为0,它占用了4个字节,那么接下来的空闲地址就是4,是1的倍数,满足要求,所以b存放的起始地址是4,占用一个字节。接下来的空闲地址为5,而c是int变量,占用4个字节,5不是4的整数倍,所以向后移动,找到离5最近的8作为存放c的起始地址,c也占用4字节,所以最后使得结构体的大小为12。现在我们再来看看下面的代码:

#include 

typedefstructstu1

{

chararray[7];

}stu1;

typedefstructstu2

{

doublefa;

}stu2;

typedefstructstu3

{

stu1 s;

charstr;

}stu3;

typedefstructstu4

{

stu2 s;

charstr;

}stu4;

voidmain()

{

printf("sizeof(stu1)    :\t%d\n",sizeof(stu1));

printf("sizeof(stu2)    :\t%d\n",sizeof(stu2));

printf("sizeof(stu3)    :\t%d\n",sizeof(stu3));

printf("sizeof(stu4)    :\t%d\n",sizeof(stu4));

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值