内容正文:
9.4 共同体
在实际的程序编写中,为了减少内存空间的开销,有时需要使用几个不同(或相同)类型的变量共同用一块存储区域,以节约内存或达到一些特殊的目的,如对数据进行拆分等。在这种情况下可以使用共同体。
1.共同体的定义
共同体也称为联合(体),用union表示,一般定义形式如下:
union 共同体名
{
类型1 成员1;
类型2 成员2;
......
类型n 成员n;
}变量名;
2.用法说明
(1)“union”是共同体的标识符名,是关键字。
(2)“共同体名”可有可无。
(3)各个成员的数据类型可以不同,各个成员既可是简单的变量,又可是数组、指针等复杂变量。
(4)同结构体类似,变量名是指定义的共同体变量的名称。
3.应用举例
union value//定义联合体value
{
char c;//定义联合体成员变量
int i;
float f;
}v;//定义联合体变量
与结构体相似,这里定义了一个新的数据类型union value,并定义了一个变量名为v。它有3个成员,它们共同占用一段内存空间。共同体类型与结构体类型的主要区别在于它们在内存的存储形式的差异。
对于结构体来说,它的存储空间的大小等于其中各个成员所占内存大小之和;而共同体里的所有成员共同使用一段存储空间,它是按占用字节数最多的元素来分配空间的,而且在同一时刻只有一个成员有效。对于上面的共同体,其所占存储空间为成员f所占的内存大小(4字节)。
4.共同体变量的引用和赋值
共同体变量的引用和赋值与结构体是一样的,读者可以参照结构体进行有关的操作,但值得指出如下几点。
(1)共同体在定义时,只能对第1个成员进行初始化。
(2)共同体中各成员的首地址相同。
(3)对共同体中最近一次操作的变量才起作用,因为各成员共用一段内存空间,前几次的操作已被最近的一次操作所覆盖。
【案例9-6】分析程序运行的结果。
#include<stdio.h>
union myun//定义联合体myun
{
Struct//定义联合体成员变量
{
int x,y,z;
}u;
int k;
}a;//定义联合体变量a
void main()
{
a.u.x=4;//初始化联合体a
a.u.y=5;
a.u.z=6;
a.k=0;
printf("%d
",a.u.x);//输出结果
}
【案例小结】
(1)共同体中的成员可以是任何一种数据类型,本案例中共同体的1个成员是结构体,因为它是该共同体结构中占用存储空间最大的成员,因此该共同体的空间为该结构体的占用空间——6字节。
(2)程序最后输出的“a.u.x”的值为0,但在整个程序中好像除了对它赋过初值后就没有对它进行操作,但为什么又得不到它的初始值4呢?那是因为共同体的性质之一就是在同一时刻只有1个元素有效,因此“a.u.x”的值是离输出语句最近一次操作后的值,在本案例中即“a.k =0”,所以输出时的值为0。
(3)程序运行结果为
习题
一、选择题
1.以下程序运行后,输出的结果是_____。
#include<stdio.h>
#define PT 5.5
#define S(x) PT*x*x
void main()
{
int a=1,b=2;
printf("%4.1f
",S(a+b));
}
A.49.5 B.9.5 C.22.0 D.45
习题
2.下列程序执行后输出的结果是_____。
#include<stdio.h>
#define MA(x) x*(x-1)
void main()
{
int a=1,b=2;
printf("%d
",MA(1+a+b));
}
A.6 B.8 C.10 D.12
3.有如下程序:
#include<stdio.h>
#define N 2
#define M N+1
#define NUM 2*M+1
void main()
{
int i;
for(i=1;i<NUM;i++)
printf("%d
",i);
}
该程序中的for循环执行的次数是_____。
A.5 B.7 C.6 D.8
4.以下程序输出的结果是_____。
#include<stdio.h>
#define SQR(X) X*X
void main()
{
int a=16,k=2,m=1;
a/=SQR(k+m)/SQR(k+m);
printf("%d
",a);
}
A.2 B.16 C.9 D.1
5.以下程序输出的结果是_____。
#include<stdio.h>
#define M(x,y,z) x*y+z
void main()
{
int a=1,b=2,c=3;
printf("%d
"