文章目录
联合体的声明和结构体类似,但他的行为却和结构体不同。联合体所有成员引用的是内存中相同位置。当你想在不同时刻把不同东西存在同一个位置时可以使用联合体。看一个简单的例子。
union {
floatf;
inti;
}fi;
fi.f=3.14159;
printf("fi.i = %d\n", fi.i);
在一个浮点型和整形都是32位的机器上,变量fi只占据内存中一个32位字,当f被使用时,这个字就作为浮点型值被访问;单i被使用时,这个字就作为整形值被访问。简单说就是同一块内存,被翻译成不同类型的数据,如何翻译取决于定义的数据类型。上面程序运行结果。
fi.i= 1078530000
联合体的作用
为什么使用联合体,当你只想看浮点型数如何存储在一种特定的机器上,但对其他类型不感兴趣时,联合体可能适合你。看一个例子。
BASIC需要记住程序使用的变量值,他提供了几种不同类型的变量。每个变量的类型必须和他的值一起存储。这里定义了一个结构用来存储这种信息,但是效率并不高。
structVARIABLE{
enum {INT, FLOAT,STRING} type;
int int_value;
float float_value;
char *string_value;
};
当BASIC程序中一个变量被创建时,就创建一个这种类型的结构用来记录变量的类型,根据变量的类型,把变量的值存储在三个字段中的一个。这个结构的低效之处在于,每次都有两个字段被浪费,因为一个变量只有一种数据类型。联合可以减少这种浪费,把三个字段存储在同一块内存区域并不会产生冲突,在某个时刻,联合中只有一个字段会被使用。
structVARIABLE {
enum { INT, FLOAT, STRING} type;
union {
int i;
float f;
char *s;
}value;
};
如果联合体的各个成员具有不同的变量,联合的长度等于最长成员的长度。
联合体-变体记录
内存中某个特定的区域将在不同时刻存储不同类型的值,在有些情况下,这些值比简单的整型或浮点型更为复杂,它们每一个都是一个完整的结构。这个例子取自一个存货系统,他记录两个不同实体:零件(part)和装配件(subassembly)。
structPARTINFO {
int cost;
int supplier;
...
};
structSUBASSYINFO {
int n_parts;
struct {
char partno[10];
short quan;
}parts[MAXPARTS];
};
接下来的存货(inventory)记录了包含每个项目的一般信息,包括一个联合,或者用于存储零件信息,或者用于存储转配件信息。
structINVREC {
charpartno[10];
intquan;
enum {PART, SUBASSY} type;
union {
structPARTINFOpart;
structSUBASSYINFO subassy;
}info;
};
在一个成员长度不同的联合体里,分配给联合体的内存数量取决于最大成员长度。如果这些成员长度相差悬殊,当存储长度较短成员时会浪费内存,在这种情况下更好的方法是在联合体重存储指向不同成员的指针,而不是存储成员本身。所有指针的长度都是相同的,这样就解决内存浪费的问题。当决定存储那个成员时,分配正确数量的内存来存储该成员。
联合的初始化
联合变量可以被初始化,但这个初始值必须是联合的第一个成员的类型,而且它必须位于一对花括号内。例如,
union {
int a;
float b;
char c[4];
}x= {5};
x.a 初始化为5.我们不能把这个变量初始化为一个浮点型或者字符值。如果给出的类型是任何其他类型的值,会被强制转化为整型并赋值给x.a。