zoukankan      html  css  js  c++  java
  • 转载学习结构体和union大小的问题

    请牢记以下3条原则:(在没有#pragma pack宏的情况下)

    1:数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储。

    2:结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.)

    3:收尾工作:结构体的总大小,也就是sizeof的结果,.必须是其内部最大成员的整数倍.不足的要补齐.

    等你看完此3条原则,2分钟已经过去,抓紧时间,实战3分钟:

    typedef struct bb
    {
     int id;             //[0]....[3]
     double weight;      //[8].....[15]      原则1
     float height;      //[16]..[19],总长要为8的整数倍,补齐[20]...[23]     原则3
    }BB;

    typedef struct aa
    {
     char name[2];     //[0],[1]
     int  id;         //[4]...[7]          原则1

     double score;     //[8]....[15]    
     short grade;    //[16],[17]        
     BB b;             //[24]......[47]          原则2
    }AA;

    int main()
    {
      AA a;
      cout<<sizeof(a)<<" "<<sizeof(BB)<<endl;
      return 0;
    }

    结果是

    48 24
    ok,上面的全看明白了,内存对齐基本过关.

    再讲讲#pragma pack().

    在代码前加一句#pragma pack(1),你会很高兴的发现,上面的代码输出为

    32 16
    bb是4+8+4=16,aa是2+4+8+2+16=32;

    这不是理想中的没有内存对齐的世界吗.没错,#pragma pack(1),告诉编译器,所有的对齐都按照1的整数倍对齐,换句话说就是没有对齐规则.

    明白了不?

    那#pragma pack(2)的结果又是多少呢?对不起,5分钟到了,自己去测试吧.

    ===============================================================

    一会搞定union内存字节对齐

    也是转载一个论坛的回复:

    其实union(共用体)的各个成员是以同一个地址开始存放的,每一个时刻只可以存储一个成员,这样就要求它在分配内存单元时候要满足两点:  
      1.一般而言,共用体类型实际占用存储空间为其最长的成员所占的存储空间;  
      2.若是该最长的存储空间对其他成员的元类型(如果是数组,取其类型的数据长度,例int   a[5]为4)不满足整除关系,该最大空间自动延伸;  
       
      我们来看看这段代码:  
      union   mm{  
      char   a;//元长度1  
      int   b[5];//元长度4  
      double   c;//元长度8  
      int   d[3];  
      };  
      本来mm的空间应该是sizeof(int)*5=20;但是如果只是20个单元的话,那可以存几个double型(8位)呢?两个半?当然不可以,所以mm的空间延伸为既要大于20,又要满足其他成员所需空间的整数倍,即24  
       
      所以union的存储空间先看它的成员中哪个占的空间最大,拿他与其他成员的元长度比较,如果可以整除,ok

  • 相关阅读:
    MVC4笔记 @functions @model @using
    NET平台4.0 发布网站流程及出错总结
    C#读写txt文件的方法
    jQuery Validate验证框架详解(转)
    用C#写的读写CSV文件
    devexpress 数据导入(gridcontrol 导出 csv)
    DevExpress XtraGrid 数据导出导入Excel
    DevExpress 表中数据导出
    DevExpress 重编译 替换强命名 修改源码
    Delphi 的运算符列表
  • 原文地址:https://www.cnblogs.com/lzlsky/p/2641834.html
Copyright © 2011-2022 走看看