5.4 C51的联合
在C51语言中,除了前面介绍的数组、指针和结构外,还有其他一些聚合数据类型,本章将介绍的联合也是一种特殊形式的聚合数据结构,也叫共用体。
5.4.1 联合的声明和使用
联合是将不同的变量组织成一个整体的数据类型,以union作为关键字。联合中的变量在内存中共用同一内存单元,因此联合类型也称为共用体。只是在这个存储空间内,不同的时间保留不同的数据类型和长度的变量,每一时刻只有一个有效。
1.联合和联合变量的声明
在C51语言中,联合的声明方式如下。
union联合名
{
数据类型成员名;
数据类型成员名;
……
};
其中,union是联合类型的关键字。同结构一样,在定义联合时,同时可以声明联合变量,其一般形式如下。
union联合名
{
数据类型成员名;
数据类型成员名;
……
}联合变量名;
示例如下。
union char_int
{
char ch;
int i;
}a;
另外,也可以先声明联合,再声明联合变量,示例如下。
union char_int
{
char ch;
int i;
};
union char_int a;
本例中,联合变量a的字符型成员ch和整型成员i长度相同,所占的内存大小一致,共用同一个内存位置。如果联合变量中成员变量的长度大小不一致,编译系统会自动取其中成员变量最大的长度为整个联合变量的长度,示例如下。
union ThreeInOne
{
int a;
char b;
float c;
}bs;
本例中,定义了联合ThreeInOne,并同时定义了一个联合变量bs。其中长度最大的成员变量是浮点型的c,因此联合变量的长度与成员变量c的长度保持一致,即占用4个字节。
2.联合变量成员的引用
联合体变量成员的引用方法与结构变量成员的引用十分相似,其一般表示方法如下。
联合体变量名.成员名
例如,对于前面定义的bs,其成员引用为bs.a、bs.b、bs.c。
与结构变量成员的引用不同的是,在某一时刻,该联合变量在内存位置只保留某一数据类型和长度的变量。联合体变量成员引用的程序示例如下。
include<stdio.h>//头文件
void main()//主函数
{
union ThreeInOne//定义联合并声明联合变量
{
int a;
char b;
float c;
}Bs;
Bs.a=9;//使用成员变量a
printf(“Bs.a=%d\n”,Bs.a);
printf(“Bs.c=%f\n”,Bs.c);//无意义
Bs.c=5.3;//使用成员变量b
printf(“Bs.c=%f\n”,Bs.c);
Bs.b=‘A’;//使用成员变量c
printf(“Bs.b=%c\n”,Bs.b);
//printf(“Bs.a=%d\n”,Bs.a);//无意义
}
该程序可以在KeilµVision3编译环境中执行,运行的结果如下。
Bs.a=9
Bs.c=0.000000
Bs.c=5.300000
Bs.b=A
在本程序中,首先为成员变量a赋值,此时引用a是有效的,第2个输出语句引用了成员变量c是无效的,因此输出零结果。当对成员变量c赋值后,才可以使用成员变量c。
注意不能同时引用联合变量成员,因为成员共用同一个内存位置,在某一时刻,该内存位置只保留某一数据类型和长度的变量,所以在程序中只能一次引用其中之一的成员。
3.联合变量指针
在C51语言中,也可以定义联合变量型指针,即将该指针指向的变量的地址赋给该联合变量指针。当联合变量定义为指针时,要用“->”符号来访问联合变量的成员,其一般表示形式如下。
联合变量指针名->成员名
联合变量指针的程序示例如下。
include<stdio.h>//头文件
void main()//主函数
{
int i=10;//声明变量并初始化
float f=3.7;
char c=‘A’;
union ThreeInOne//声明联合
{
int a;
char b;
float c;
};
union ThreeInOne*un;//声明联合变量指针
un=&i;//为联合变量指针赋值
printf(“un->a=%d\n”,un->a);//输出
un=&c;
printf(“un->b=%c\n”,un->b);
un=&f;
printf(“un->c=%f\n”,un->c);
}
该程序可以在KeilµVision3编译环境中执行,运行的结果如下。
un->a=10
un->b=A
un->c=3.700000
在本程序中,首先声明一个联合变量指针un,然后分别对un进行赋值,并打印输出结果。
4.联合数组
在C51语言中,联合变量也可以定义成数组,即数组中的各数组元素都是联合型变量。由于一次只能引用其中一个成员,所以在使用联合数组时,对于每个数组元素,每次只能对其一个成员赋值,联合数组的程序示例如下。
include<stdio.h>//头文件
void main()//主函数
{
union ThreeInOne//声明联合
{
int a;
char b;
float c;
};
union ThreeInOne un[3];//声明联合数组变量
un[0].a=10;//分别给各数组元素赋值
un[1].b=3.7;
un[2].c=‘A’;
printf(“un[0].a=%d\n”,un[0].a);//输出各数组元素的成员变量值
printf(“un[1].b=%c\n”,un[1].b);
printf(“un[2].c=%f\n”,un[2].c);
}
该程序可以在KeilµVision3编译环境中执行,运行的结果如下。
un[0].a=10
un[1].b=A
un[2].c=3.700000
本例中,先声明一个联合变量型数组un,其有3个数组元素:un[0]、un[1]、un[2]。然后分别对其中的每个数组元素进行赋值,即为各联合变量的成员赋值,为相应的成员赋相应的数据类型的值。最后分别打印输出各数组元素的值,即各联合变量的成员值。
5.联合和结构嵌套
在C51语言中,联合和结构可以嵌套使用,这两种数据结构嵌套使用时,会出现两种情况,即联合可以出现在结构体内,联合内的成员也可以是结构型变量。下面分别介绍这两种情况。
❑联合内的成员是结构型变量。
联合内的成员是结构型变量,引用该联合的结构型变量成员的表示方法如下。
联合变量名.结构变量名.成员名
示例如下。
union ThreeInOne
{
int a;
char b;
float c;
struct
{
int a;
char b;
float c;
}st;
}un;
本例中,声明了一个联合ThreeInOne和一个联合变量un,在联合ThreeInOne内,又声明了一个结构型成员变量st,该联合的成员变量的引用为un.a、un.b、un.c、un.st.a、un.st.b和un.st.c。
❑联合出现在结构体中。
联合可以出现在结构体内,作为结构的联合型成员变量,引用该联合的结构型变量成员的表示方法如下。
.结构变量名.联合变量名.成员名
示例如下。
struct ThreeInOne
{
int a;
char b;
float c;
union
{
int a;
char b;
float c;
}un;
}st;
本例中,声明了一个结构ThreeInOne和一个结构变量st,在结构ThreeInOne内,又声明了一个联合型成员变量un,该结构的成员变量的引用为st.a、st.b、st.c、st.un.a、st.un.b和st.un.c。