联合体(union)

联合体和结构体一样,也是一个不同数据类型的集合,但在为其成员分配内存方面有所不同。

联合体分配的内存大小等于所有成员中占空间最大的成员的内存空间,并且该空间与其他所有成员共享。

语法如下:

union tag_name[optionl]{
   dataType member1;
   dataType member2;
   ................;  
   ................;
   dataType memebrn;
}union_variable_Name;

tag_name是可选的,可以不写。

例如:

union empInfo
{
 unsigned char name[20];
 unsigned int empId;
 double  salary;
}emp;
 
或者
union empInfo 
{ 
  unsigned char name[20]; 
  unsigned int empId; 
  double salary; 
};
union empInfo emp;

sizeof(emp)=20 byte(name 是联合体中所占空间最大的成员,因此联合体的大小等于name的大小)

由于三个成员的姓名,工号和薪资之间共享20个字节,因此一次读或写一个成员。
如果你想像使用结构体一样同时给三个成员赋值,那么最新的成员将会覆盖旧的成员。
例如,分别给联合体的三个成员赋值,并打印输出查看内存覆盖情况:

#include <stdio.h>
 
union empInfo
{
 unsigned char name[20];
 unsigned int  empId;
 double        salary;
};
 
 
int main() 
{
    union empInfo emp={"孙悟空",12345,89999.466};
    
    printf("Size of union empInfo is =%lu\n",sizeof(union empInfo));
    
    printf("联合体的成员:\n");
    
    printf("emp.name=%s\n",emp.name);
    
    printf("emp.empId=%u\n",emp.empId);
    
    printf("emp.salary=%lf\n",emp.salary);
 
    return 0;
}

输出结果:

Size of union empInfo is =24
联合体的成员:
emp.name=孙悟空
emp.empId=1852337994
emp.salary=0.000000

由上面例程可以看到emp.empId和emp.salary有一些垃圾值,因为它已被emp.name覆盖。

注意:

  1. 由于内存对齐原因,以上联合体大小为24个字节。
  2. 联合体的成员地址是无法获取的,因为该地址在所有成员之间共享。
  3. 除了内存共享差异,联合体几乎与结构体相同,因此在结构体中看到的所有概念也将适用于联合体。