共用体union:几个不同类型的变量共享同一段内存的结构,称为共用体(定义是核心)。
共用体的定义、声明均与结构体一样,定义共用体类型一般形式为:
union 共用体名
{
成员列表;
}变量列表;
例如:
union Data
{ //表示不同类型的变量i、ch、f可以存放到同一段存储单元中。
short i;
char ch;
float f;
}a,b,c; //在声明类型的同时定义变量
在内存中存储如下:
因此,在分配内存时,总是以成员中占内存最大的类型分配,即sizeof(a)=4;
使用共用体时应注意:
1、同一内存段可以用来存放几种不同类型的成员,但在每一瞬间只能存放其中一个成员,而不是同时存放几个;
2、可以对共用体变量初始化,但初始化表中只能有一个常量;
union Data
{
short i;
char ch;
float f;
}a={1,'c',1.05};//错误
union Data a={16}; //正确,对第一个成员初始化
union Data a={.ch='k'};//C99允许对指定的一个成员初始化
3、共用体变量中起作用的成员是最后一次被赋值的成员,在对共用体变量中的一个成员赋值后,原有变量存储单元中的值就被取代。
4、共用体变量的地址和它的各成员的地址都是同一地址。
5、不能对共用体变量名赋值,也不能企图引用变量名来得到一个值。C99允许同类型的共用体变量相互赋值,如:
union Data a=16;//错误,不能对共用体变量直接赋值;
union Data a={16};//正确,对第一个成员初始化;
union Data a={16},b;
b=a;//合法,a和b是同一类型。
6、C99允许用共用体作为函数参数;
7、共用体可以作为结构体成员出现在结构体中,结构体也可以作为共用体成员出现在共用体中。
干货,一道笔试题:利用union编写程序判断CPU是big-endian还是litter-endian
#include<stdio.h>
int main()
{
union Test
{
unsigned int a;
unsigned char b;
}tmp={0x12345678};
//如果打印出的是0x78,表明是litter-endian
//如果打印出的是0x12,表明是big-endian
if(tmp.b==0x78)
printf("The endian of cpu is litter.\n");
else
printf("The endian of cpu is big.\n");
return 0;
}
参考书籍:《C程序设计(第四版)》 谭浩强著