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。