结构体是将一个对象(内存空间)解释为C语言中多种类型的综合.
联合 是将一个对象(内存空间)在不同时候解释为C语言中不同的类型.
// 联合
union {
float f;
int i;
} fi;
当使用 fi.f
时, fi所占内存中的内容将被解释为一个float数; 当使用 fi.i
时, fi所占内存中的内容将被解释为一个int类型.
注意: 如果联合的各个成员具有不同的长度, 联合的长度就是最长成员的长度.
可以对联合进行初始化, 但是初始值必须是联合第一个成员的类型.
// 联合初始化
union {
float f;
int i;
} fi = ( 3.1415 }; // fi.f初始化为3.1415
变体记录 可以看作联合的升级版, 变体记录中联合成员是比int float更为复杂的结构.
考虑下面的情况:
仓库储存两种货物, 一种是零件(part), 一种是装配件(subassembly), 装配件由一些零件组成. 一个零件信息包括零件成本, 零件供应商编号; 一个装配件信息包括组成装配件的零件数, 以及零件信息. 显然, 仓库的一条存货记录(inventory)可能是零件, 也可能是装配件, 并且包含入库日期和操作员编号, 可以用变体记录实现.
// 零件
struct PARTINFO {
int cost; // 零件成本
int supplier; // 供应商编号
};
// 装配件
struct SUBASSYINFO {
int n_parts; // 零件数
PARTINFO parts[MAXPARTS]; // 每个零件信息
};
// 存货记录
struct INVREC {
char date[9]; // 入库日期
int oper; // 操作员编号
enum (PART, SUBASSY} type;
union {
struct PARTINFO part;
struct SUBASSYINFO subassy;
} info;
} record;
我们可以通过以下方式访问存货记录record.
record.oper
获取存货操作员编号if(record.type == PART)
(存货为零件, info为info.part)
record.info.part.cost
获取存货零件成本
record.info.part.supplier
获取存货零件供应商编号if(record.type == SUBASSY)
(存货为装配件, info为info.subassy)
record.info.subassy.n_parts
获取存货装配件包含零件数
record.info.subassy.parts[0].cost
获取存货装配件第一个零件的成本