struct 结构体 、 union 枚举 及 #pragma pack 字节对齐

1 篇文章 0 订阅
【字节对齐】
   <note>
     1. ## 自身实践经验总结 ## 
         1. ### 例子
           /*C在线编译,C语言web在线运行平台(不支持输出中文)*/
           //  http://yishouce.com/c/run  
            #include <stdio.h>
            #include <string.h>

            #pragma pack (1)    // 注. 如果这里改成 2 或 4,结果就不一样了。
            struct aa {
                  int a;     
            } ;
            #pragma pack ()

            #pragma pack (8)  
            struct bb{
              char a;        // [0, 1]
              struct aa b;   // [1, 5]  把 b 当成一个变量,大小 4,自身对齐 1
            }; 
           #pragma pack ()

           void main(void)
            {
              printf("%d\n",sizeof(struct aa));    // 输出 4
              printf("%d\n",sizeof(struct bb));    // 输出 5
              printf("------------------\n");
            }
         2. ### 例子 2  union 字节对齐
           /*C在线编译,C语言web在线运行平台(不支持输出中文)*/
           //  http://yishouce.com/c/run 
          #include <stdio.h>
          #include <string.h>
          #define OFFSET(st, field)     (size_t)&(((st*) 0)->field)

          // 选最大的 4 * 5 = 20, 但自身对齐 8 字节, 所以 ---> [0 - 24]  
          typedef union { double i;  int k[5]; char c;} DATE; 

           // DATE 当成一个变量,自身对齐 8 字节 
          typedef struct data4 { char cat; DATE dag;} data4; 

          void main(void)
          {
            printf("%d\n",sizeof(DATE));           // 输出 24

            printf("%d\n",OFFSET(data4, dag));     // 输出 8

            printf("%d\n",sizeof(struct data4));   // 输出 32, 即:  [0 ~ 8] [8 ~ 32]

          }


     2. ## 学习记录 记忆索引点 ##
        1. ###  对齐参数   
           # http://www.cnblogs.com/dolphin0520/archive/2011/09/17/2179466.html
         除了变量的 <自身对齐参数> 外,还有一个对齐参数,
         就是每个<编译器默认的对齐参数> #pragma pack(n),这个值可以通过代码去设定,
         如果没有设定,则取系统的默认值。
        在windows(32) / VC6.0下,n 的取值可以为 1248,默认情况下为 8。
        在linux(32)/GCC下,n的取值只能为124,默认情况下为42. ### <自身对齐原则>和<整体对齐原则>
         ※ 每个 <变量> 相对于结构体的 <首地址的偏移量> 必须是<对齐参数的整数倍>,
         这句话中的对齐参数是取: min(自身对齐参数, #pragma pack(n)) 。
         举例: 
         比如在结构体 A 中有变量int a,a的自身对齐参数为4(环境为windows/vc),
         而 VC 默认的对齐参数为 8,取较小者,则对于a,
         它相对于结构体 A 的起始地址的偏移量必须是 4 的倍数。

         ※ <结构体整体变量> 所占空间的大小是<对齐参数>的整数倍。
         这句话中的对齐参数有点复杂它是取结构体中: min (所有变量的对齐参数的最大值, 
         系统默认对齐参数 #pragma pack(n))。
         举个例子:
          ① #pragma pack(2)  struct {int a, short b} , 整体便是 min (max(a,b) , 2) = 2;#pragma pack(8)  struct {int a, short b} , 整体便是 min (max(a,b) , 8) = 4;

        3. ### 结构体的继承关系  # http://www.cnblogs.com/webary/p/4721017.html 
            ※ 基类的成员总是在派生类的前面。而且即使有字节对齐,
            基类对齐后派生类的成员不会占用基类填充的字节,即计算好基类所占字节数后,这些字节只能由基类拥有,
            不能被派生类的成员占用。
            举例:
             struct A {
                int a;
                char b;
            };
            struct B:A {  // 注意是 A 整体对齐后,才开始 B 的成员。
                char c;
                int  d;
                long long e;
            };
            /*
              0   4   8   12  16     24
              |   |   |   |   |      |
              aaaab---c---ddddeeeeeeee
            */

         4. ### 

     3. xxxx ...
     // 参考资料
     http://www.cnblogs.com/dolphin0520/archive/2011/09/17/2179466.html  
     // 结构体字节对齐 [note: 表格不错,不同平台上 double 值自身对齐方式不一样]

     http://www.cnblogs.com/mashang/archive/2011/03/24/1993512.html      
     // 字节对齐详解 [note: 例子挺不错的]

     http://www.cnblogs.com/webary/p/4721017.html            
     // struct / class等内存字节对齐问题详解 [note: 继承的例子不错]

     http://www.cnblogs.com/clover-toeic/p/3853132.html    
     /* C语言字节对齐问题详解 [note: OFFSET宏定义可取得指定结构体某 <成员> 
      在结构体内部的<偏移>:  #define OFFSET(st, field)  (size_t)&(((st*) 0)->field) ] 
     */

    http://blog.chinaunix.net/uid-20672257-id-3138843.html 
    /* struct的成员对齐问题-结构体实际大小问题 
     [note : 例子输出和文中不一致,可以尝试在在线运行平台自己试试]
     */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值