C/C++中的联合体

时间:2022-06-01 18:14:03

利用union可以用相同的存储空间存储不同型别的数据类型,从而节省内存空间。当访问其内成员时可用"."和"->"来直接访问。

 

当多个数据需要共享内存或者多个数据每次只取其一时,可以利用联合体(union)。在C Programming Language 一书中对于联合体是这么描述的:
1)联合体是一个结构;
2)它的所有成员相对于基地址的偏移量都为0;
3)此结构空间要大到足够容纳最"宽"的成员;
4)其对齐方式要适合其中所有的成员;

演示代码如下:

 

[cpp] view plaincopyprint?
  1. #include<iostream>  
  2. using namespace std;  
  3.   
  4. union U1  
  5. {  
  6.     int n;  
  7.     char s[11];  
  8.     double d;  
  9. };  
  10.   
  11. union U2  
  12. {  
  13.     int n;  
  14.     char s[5];  
  15.     double d;  
  16. };  
  17.   
  18. int main()  
  19. {  
  20.     U1 u1;  
  21.     U2 u2;  
  22.     cout<<sizeof(u1)<<'\t'<<sizeof(u2)<<endl;  
  23.     cout<<"u1各数据地址:\n"<<&u1<<'\t'<<&u1.d<<'\t'<<&u1.s<<'\t'<<&u1.n<<endl;  
  24.     cout<<"u1各数据地址:\n"<<&u2<<'\t'<<&u2.d<<'\t'<<&u2.s<<'\t'<<&u2.n<<endl;  
  25. }  

上述代码中:

 

对于U1联合体,s占11字节,n占4字节,d占8字节,因此其至少需1字节的空间。然而其实际大小并不是11,用运算符sizeof测试其大小为16。这是因为这里存在字节对齐的问题,11既不能被4整除,也不能被8整除。因此补充字节到16,这样就符合所有成员的自身对齐了。从这里可以看出联合体所占的空间不仅取决于最宽成员,还跟所有成员有关系,即其大小必须满足两个条件:1)大小足够容纳最宽的成员;2)大小能被其包含的所有基本数据类型的大小所整除。

对于U2联合体,同理知道,用运算符sizeof测试其大小为8。

 

具体运行结果如下:

C/C++中的联合体
从结果图中还可以发现,联合体中的各数据的存储地址都是相同的。

 

上面提到了联合体中的数据是共享相同的存储空间。下面再研究具体每种类型数值都存储在哪里?

 

[cpp] view plaincopyprint?
  1. #include<iostream>  
  2. using namespace std;  
  3.   
  4. union U  
  5. {  
  6.     unsigned int n;  
  7.     unsigned char s[4];  
  8. };  
  9.   
  10. int main()  
  11. {  
  12.     U u;  
  13.     u.n = 0xf1f2f3f4;  
  14.     cout<<hex<<u.n<<'\t'<<&u.n<<endl;  
  15.     cout<<hex<<(int)u.s[0]<<'\t'<<(void*)&u.s[0]<<endl;  
  16.     cout<<hex<<(int)u.s[1]<<'\t'<<(void*)&u.s[1]<<endl;  
  17.     cout<<hex<<(int)u.s[2]<<'\t'<<(void*)&u.s[2]<<endl;  
  18.     cout<<hex<<(int)u.s[3]<<'\t'<<(void*)&u.s[3]<<endl;  
  19. }  

 

上述代码中,联合体U中,n占4字节,s[4]也占4字节。故联合体共占4字节。

程序输出如下:

C/C++中的联合体


这说明,内存中数据低位字节存入低地址,高位字节存入高地址,而数据的地址采用它的低地址来表示。