关闭

C语言的那些小秘密之字节对齐

发表于:2011-12-15 10:25

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:bigloomy(CSDNblog)    来源:51Testing软件测试网采编

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

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

  1. #include <stdio.h>   
  2.   
  3. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)   
  4.   
  5. typedef struct stu1  
  6. {     
  7.     int a;  
  8.     char b[1];  
  9.     int c;  
  10. }stu1;  
  11.   
  12. void main()  
  13. {  
  14.     printf("offsetof(stu1,a):\t%d\n",offsetof(stu1,a));   
  15.     printf("offsetof(stu1,b):\t%d\n",offsetof(stu1,b));   
  16.     printf("offsetof(stu1,c):\t%d\n",offsetof(stu1,c));   
  17.     printf("sizeof(stu1)    :\t%d\n",sizeof(stu1));   
  18. }

  运行结果为:

  1. offsetof(stu1,a):       0  
  2. offsetof(stu1,b):       4  
  3. offsetof(stu1,c):       8  
  4. sizeof(stu1)    :       12  
  5. Press any key to continue

  对于字节对齐不了解的读者可能有疑惑的是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。现在我们再来看看下面的代码:

  1. #include <stdio.h>   
  2.   
  3. typedef struct stu1  
  4. {     
  5.     char array[7];  
  6. }stu1;  
  7.   
  8. typedef struct stu2  
  9. {     
  10.     double fa;  
  11. }stu2;  
  12.   
  13. typedef struct stu3  
  14. {     
  15.     stu1 s;  
  16.     char str;  
  17. }stu3;  
  18.   
  19. typedef struct stu4  
  20. {     
  21.     stu2 s;  
  22.     char str;   
  23. }stu4;  
  24.   
  25. void main()  
  26. {  
  27.     printf("sizeof(stu1)    :\t%d\n",sizeof(stu1));   
  28.     printf("sizeof(stu2)    :\t%d\n",sizeof(stu2));  
  29.     printf("sizeof(stu3)    :\t%d\n",sizeof(stu3));  
  30.     printf("sizeof(stu4)    :\t%d\n",sizeof(stu4));  
  31. }

53/5<12345>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号