14.10 联合简介

联合(union)是一个能在同一个存储空间里(但不同时)存储不同类型数据的数据类型。一个典型的应用是一种表,设计它是用来以某种既没有规律、事先也未知的顺序保存混合类型数据。使用联合类型的数组,可以创建相同大小单元的数组,每个单元都能存储多种类型的数据。

联合是以与结构同样的方式建立的,也是需要有一个联合模板和一个联合变量。可以在一步中定义它们,也可以使用联合标记在两步中定义。下面是一个带有标记的联合模板的例子:

广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元

阅读 ‧ 电子书库

具有类似声明的结构可以含有一个int型数值和一个double型数值以及一个char型数值,而这个联合可以含有一个int型数值或一个double型数值或一个char型数值。

下面是定义3个hold类型联合变量的例子:

阅读 ‧ 电子书库

第一个声明创建一个变量fit。编译器分配足够的空间以保存所描述的可能性的最大需要。在这种情况下,列出的最大可能性是double型数据。在我们的系统里,它需要64位,即8个字节。第二个声明创建了一个save数组,它含有10个元素,每个元素大小为8个字节。第三个声明创建了一个指针,可以存放一个hold联合的地址。

可以初始化一个联合。因为联合只存储一个值,所以初始化的规则与结构的初始化不同。具体地,有3种选择:可以把一个联合初始化为同样类型的另一个联合;可以初始化联合的第一个元素;或者,按照C99标准,可以使用一个指定初始化项目。

阅读 ‧ 电子书库

下面示例了怎样使用联合:

阅读 ‧ 电子书库

点运算符表示正在使用哪种数据类型。在同一个时间只能存储一个值。即使有足够的空间,也不能同时保存一个char类型和一个int类型的值。由您负责记住当前保存在联合中的数据的类型。

如同与指向结构的指针一起使用->运算符一样,可以与指向联合的指针一起来使用->运算符:

阅读 ‧ 电子书库

接下来的语句序列显示了什么是不能做的:

阅读 ‧ 电子书库

这个语句序列是错误的,因为存储了一个char类型,而接下来的一行却假定fit的内容是double类型的。

但是,使用一个成员来将值保存到一个联合中,然后使用一个不同的成员来查看这些内容,这种做法有时会很有用。下一章的程序清单15.4就给出了一个这样的例子。

另一个可能会使用联合的地方是在某些结构中,该结构所存储的信息有赖于其中的一个成员。例如,假定有一个表示一辆汽车的结构。如果汽车归属于使用者,就要一个结构成员来描述这个所有者。如果汽车被租赁,需要一个成员来描述租赁它的公司。那么使用下面的语句行,可以做些事情:

阅读 ‧ 电子书库

假定flits是一个car_data结构。那么如果flits.status是0,程序就可以使用flits.ownerinfo.owncar.socsecurity;如果flits.status是1,程序就可以使用flits.ownerinfo.leasecar.name。