1. 联合体、结构体定义

   联合体:在进行某些算法的C语言编程的时候,需要使几种不同类型的变量存放到同一段内存单元中。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,在C语言中,被称作“共用体”类型结构,简称共用体,也叫联合体。

   结构体:结构体(struct)是由一系列具有相同类型或不同类型的数据构成的数据集合,也叫结构。  

   由此看出,“联合”与“结构”有一些相似之处。但两者有本质上的不同。在结构中各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度。应该说明的是, 这里所谓的共享不是指把多个成员同时装入一个联合变量内, 而是指该联合变量可被赋予任一成员值,但每次只能赋一种值, 赋入新值则冲去旧值。           

2.内存分配情况                                                    大家都知道现在我们使用的主流计算机都是32位字长的CPU,对于这个类型的CPU取4个字节的数要比取一个字节高效,也更方便。所以结构体中每个成员的首地址都是4的正数倍的话,取数时就会相对高效更高效。                                     因此,就有了内存对齐。每个特定平台上的编译器都有自己的默认 对齐系数”(也叫对齐模数)。程序员可以通过预编译命令#pragma pack(n)n=1,2,4,8,16来改变这一系数,其中的n就是你要指定的“对齐系数”。

规则:

1、数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma pack指定的数值和这个数据成员自身长度中,比较小的那个进行。

2、结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐,对齐将按照#pragma pack指定的数值和结构(或联合)最大数据成员长度中,比较小的那个进行。

3、结合1、2可推断:当#pragma pack的n值等于或超过所有数据成员长度的时候,这个n值的大小将不产生任何效果。

3.举例说明

 

 
  
  1. union a { 
  2.         int a_int1; 
  3.         double a_double; 
  4.         int a_int2; 
  5.     }; 
  6.     typedef struct 
  7.     { 
  8.         a a1; 
  9.         char y; 
  10.     } b; 
  11.     class c 
  12.     { 
  13.         double c_double; 
  14.         b b1; 
  15.         a a2; 
  16.     }; 
  17.     cout<<sizeof(a)<<endl; 
  18.     cout<<sizeof(b)<<endl; 
  19.     cout<<sizeof(c)<<endl; 

    输出结果为8字节、16字节、32字节, 那么来分析下结构Union中,int为4字节,double为8字节,故联合体sizeof(a)=8。对于结构体b,a占8字节,char占1字节,然后char后面的3个字节补充对齐,构成4整数倍字节。但sizeof(b)为什么不是,8+4=12字节呢。原因在于结构体中存在联合体a,而a呢,占用的是8个字节,对齐系数变成了8。所以char后面的7个字节都是作为对齐补充的。(此处,总结结构体中,对齐系数为4的倍数的最大值为对齐系数。) 结构体c的话就好分析了sizeof(c)=8+16+8=32。