11.5 共用体
共用体的类型说明和变量的定义方式与结构体的类型说明和变量定义的方式完全相同。所不同的是,结构体中的成员各自占有自己的存储空间,而共用体的变量中的所有成员占有同一个存储空间。可以把一个整型变量、一个字符型变量、一个实型变量放在同一个地址开始的内存单元中,这3个变量在内存中所占的字节数不同,但都从同一个起始地址开始存放,也就是使用覆盖技术,几个变量相互覆盖。
考点8 共用体类型的定义和引用
真考链接
考点8 属于简单识记知识点。在选择题中的考核概率为30%。
(1)共用体类型的说明。一般地,共用体类型说明的形式为:
union 共用体标识名
{
类型名1共用体成员名1;
类型名2共用体成员名2;
…
类型名n共用体成员名n;
};
例如:union un 1
{ int i;
float x;
char ch;
};
说明:union是关键字,是共用体类型的标志。un_l是共用体标识名,“共用体标识名”和“共用体成员名”都是由用户定义的标识符。
另外,共用体标识名是可选项,在说明中可以不出现。共用体中的成员可以是简单变量,也可以是数组、指针、结构体和共用体(结构体的成员也可以是共用体)。
(2)共用体变量的定义。共用体变量的定义也和结构体一样,可以采用4种方式。
注意:
(1)共用体变量在定义的同时只能用第一个成员的类型的值进行初始化。
(2)共用体类型变量的定义,在形式上与结构体非常一致,但它们是有本质区别的:结构体中的每个成员分别占有独立的存储空间,因此结构体变量所占内存字节数是其成员所占字节数的总和;而共用体变量中的所有成员共享一段公共存储区,所以共用体变量所占内存字节数与其成员中占字节数最多的那个成员相等。
(3)正是因为共用体变量中的所有成员共享同一存储空间,因此变量中的所有成员的首地址相同,而且变量的地址也就是该变量成员的地址。
共用体变量中每个成员的引用方式与结构体完全相同,可以使用以下3种形式之一:
①共用体变量名.成员名;
②指针变量名->成员名;
③(*指针变量名).成员名。
共用体中的成员变量同样可参与其所属类型允许的任何操作,但在访问共用体成员时应注意:共用体变量中起作用的是最近一次存入的成员变量的值,原有成员变量的值将被覆盖。
真题精选
【例1】以下程序的执行结果是( )。
#include <stdio.h>
union un
{ int i;
char c[2];
}
main()
{ union un x;
x.c[0] =10;
x.c[1] =1;
printf("\n% d",x.i);
}
A.266 B.11 C.265 D.138
【答案】 A
【解析】此题考查共用体的特征。int类型变量i和字符数组c共用两个字节的存储单元,通常c[0]位于低字节,c[1]位于高字节。因此,x.i=x.c[1]*256+x.c[0] =266,故选项A正确。
【例2】以下程序的输出结果是( )。
union myun
{ struct
{int x,y,z;}u;
int k;
}a;
main()
{ a.u.x=4;a.u.y=5;a.u.z=6;
a.k=0;
printf("% d\n",a.u.x);
}
A.4 B.5 C.6 D.0
【答案】D
【解析】共用体变量中起作用的成员是最后一次存放的成员,在存入一个新的成员后原有的成员就失去作用。在本题中,当对a.u.y成员赋值时,a.u.x的值就不存在了,当对a.u.z赋值时,a.u.y的值就不存在了。
【例3】已知字符0的ASCII代码值的十进制数是48,有以下程序:
#include <stdio.h>
main()
{ union {
int i[2];
long k;
char c[4];
}r,*s=&r;
s->i[0] =0x39;s->i[1] =0x38;
printf("% x\n",s->c[0]);
}
其输出结果是( )。
A.39 B.9 C.38 D.8
【答案】 A
【解析】在共用体变量中,所有成员共用存储空间。因此变量r中,成员i[0]和成员c[0]和c[1]共用2字节的存储空间, c[0]和c[1]都占1字节,因此,c[0]与i[0]的低8位共用1字节,而c[1]与i[0]的高8位共用1字节。程序以十六进制数的形式输出s->c[0]的值,因此只需求出在i[0]的低8位中的值即可。程序有赋值语句:s->i[0] =0x39;s->i[1] =0x38;,根据以上分析,只需关心s->i[0] =0x39;的赋值即可。因为c[0]与i[0]的低8位共用1字节,所以s->c[0]的十六进制数就是39。