关于联合体union的详细解释

1.概述

联合体union的定义方式与结构体一样,但是二者有根本区别。

在结构中各成员有各自的内存空间,一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间,一个联合变量的长度等于各成员中最长的长度。

2.联合体长度

在The C Programming Language里面讲述union内存分配的原话是

1)联合体就是一个结构

2)联合体的所有成员相对于基地址的偏移量为0

3)此结构空间要大到总够容纳最“宽”的成员

4)并且,其对其方式要适合于联合体中所有类型的成员

我的理解可以概括为两点:

1)联合体的结构空间要足够大,要等于最长的一个结构变量的空间,但是这个最长的空间要满足以下条件:

     1.要大于等于最长的一个结构变量的空间

      2.并且要能够整除其他结构变量的数据长度,即联合体空间对其他成员的元类型要能够整除(int a[5],其元类型为int,元类型长度为4),实际上就是要取一个元类型的最小公倍数。

这儿举例来说

  1. union     
  2. {   
  3.     float   fuel_load;   
  4.     char a[5];  
  5.     int   pallets;   
  6. }fighter;   
	union   
	{ 
		float   fuel_load; 
		char a[5];
		int   pallets; 
	}fighter; 


这个结构体中,各个结构变量的空间分别为float   fuel_load; 占4个字节,char a[5];占5个字节,int   pallets;占4个字节。通过“3)此结构空间要大到总够容纳最“宽”的成员”这句话,我们可以认为是结构体的空间为5个字节即可,但是“其对其方式要适合于联合体中所有类型的成员”没有满足,对于这个问题,通过上面红色字体部分可以解决。,因此联合体空间为8.8可以整除 4(float、int长度)和1(char的长度),并且8大于数组5.

再举一个例子有助于大家理解。

  1. struct   aircraft   
  2. {   
  3. int   wingspan;   
  4. int   passengers;   
  5. union     
  6. {   
  7. float   fuel_load;   
  8. float   bomb_load;   
  9. int   pallets;   
  10. };   
  11. }fighter;   
struct   aircraft 
{ 
int   wingspan; 
int   passengers; 
union   
{ 
float   fuel_load; 
float   bomb_load; 
int   pallets; 
}; 
}fighter; 


 

sizeof(fighter) 是12 。int   wingspan; int   passengers;两个int型 8个字节。union中 3个都是4个字节,因此union长度为4个字节。 

3.内存分配

一句话:联合体变量的各个成员都是从低字节开始公用的。即:所有的成员都是从低字节开始的。

我们先为整个union分配一个空间,这个空间大小就是上面(2)内存分配中所讲述的。

  1. union {  
  2.       int i;  
  3.       char x[2];  
  4. }a;  
  5. int main(void)  
  6. {  
  7.    a.x[0] = 10;  
  8.    a.x[1] = 1;  
  9.    printf("%d\n",a.i);  
  10.    return 0;  
  11. }  
union {
      int i;
      char x[2];
}a;
int main(void)
{
   a.x[0] = 10;
   a.x[1] = 1;
   printf("%d\n",a.i);
   return 0;
}


其内存如下图所示。a.x[0] 处于低字节,x[1]高字节。当调用i这个成员变量的时候,其开始地址仍然是从起始地址开始,数4个字节输出。因此为 256 + 10 = 266

程序附上:

  1. #include <string.h>   
  2. #include <stdio.h>   
  3. #include <unistd.h>   
  4. #if 0   
  5. typedef union data{  
  6.      float a;  
  7.      float b;  
  8.      int c;  
  9. }data_t;  
  10. int main(int argc ,char **argv)  
  11. {  
  12.   
  13.      printf("sizeof(float):%d\nsizeof(data_t):%d\n",sizeof(float),sizeof(data_t));  
  14.      return 0;  
  15.   
  16.   
  17. }  
  18. #endif   
  19. typedef union data{  
  20.      int i;  
  21.      char x[2];  
  22. }data_t;  
  23. int main(int argc ,char **argv)  
  24. {  
  25.   
  26.         data_t datab;  
  27.      memset(&datab,0,sizeof(datab));  
  28.      datab.x[0] = 10;  
  29.      datab.x[1] = 1;  
  30.       
  31.         printf("sizeof(float):%d\nsizeof(int):%d\n",sizeof(float),sizeof(int));  
  32.      printf("datab.i :%d\n",datab.i);  
  33.      return 0;  
  34.   
  35.   
  36. }  
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#if 0
typedef union data{
     float a;
     float b;
     int c;
}data_t;
int main(int argc ,char **argv)
{

     printf("sizeof(float):%d\nsizeof(data_t):%d\n",sizeof(float),sizeof(data_t));
     return 0;


}
#endif
typedef union data{
     int i;
     char x[2];
}data_t;
int main(int argc ,char **argv)
{

        data_t datab;
     memset(&datab,0,sizeof(datab));
     datab.x[0] = 10;
     datab.x[1] = 1;
    
        printf("sizeof(float):%d\nsizeof(int):%d\n",sizeof(float),sizeof(int));
     printf("datab.i :%d\n",datab.i);
     return 0;


}

4.附录 各个数据类型的长度

type bytes

int  4

char 1

short int 2

bool 1

long 4

long long 8

float 4

double 8

long double 8

  1. <PRE class=cpp name="code"> </PRE>  
  2. <PRE></PRE>  
  3. <PRE></PRE>  
  4. <PRE></PRE>  
  5. <PRE></PRE>  
<div class="dp-highlighter bg_cpp"><div class="bar"><div class="tools"><strong>[cpp]</strong> <a target=_blank class="ViewSource" title="view plain" href="http://blog.csdn.net/yankai0219/article/details/6892189#">view plain</a><a target=_blank class="CopyToClipboard" title="copy" href="http://blog.csdn.net/yankai0219/article/details/6892189#">copy</a><a target=_blank class="PrintSource" title="print" href="http://blog.csdn.net/yankai0219/article/details/6892189#">print</a><a target=_blank class="About" title="?" href="http://blog.csdn.net/yankai0219/article/details/6892189#">?</a></div></div><ol class="dp-cpp"><li class="alt"><span><span>  </span></span></li></ol></div><pre style="DISPLAY: none" class="cpp" name="code"> 
 
 
 
 
 
 
 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值