C语言结构和联合——联合
聚合数据类型能够同时存储超过一个的单独数据。c提供了两种类型的聚合数据类型,数组和结构。数组是相同类型的元素的集合,通过下标引用或者指针间接访问。结构是不同类型的成员的集合,由于结构的成员长度可能不同,通过成员名来访问。
联合的声明和结构类似,但它的行为方式却和结构不同。联合的所有成员引用的是内存中相同位置。为什么会有类似这样的数据形式呢,以BASIC解释器为例,通过结构体存储变量的值:
struct VARIABLE
{
enum
{
INT, FLOAT, STRING
} type;
int int_value;
float float_value;
char *string_value;
};
当BASIC程序中的一个变量被创建时,解释器就要创建这样一个结构,浪费两个没有使用的值字段。改成联合体就可以减少这种浪费:
struct VARIABLE
{
enum
{
INT, FLOAT, STRING
} type;
union
{
int i;
float f;
char *s;
}value;
};
下面是一个自动存货的例子,记录两种不同的实体:零件(part)和装配件(subassembly)。零件有购买价格和购买来源两种属性,配件由零件组成。
struct PARTINFO
{
int cost;
int supplier;
};
struct SUBASSYINFO
{
int n_parts;
struct {
char partno[10];
short quan;
}parts[MAXPARTS];
};
struct INVREC
{
char partno[10];
int quan;
enum {PART, SUBASSY} type;
union {
struct PARTINFO part;
struct SUBASSYINFO subassy;
}info;
};
struct INVREC rec;
if (rec.type == PART)
{
y = rec.info.part.cost;
z = rec.info.part.supplier;
}
else
{
y = rec.info.subassy.n_parts;
z = rec.info.subassy.parts[0].quan;
}
在一个成员长度不同的联合体里,分配给联合的内存数量取决于它的最长成员的长度。如果成员的长度相差悬殊,存储较短长度的成员时,浪费的空间是相当可观的。这种情况下,更好的方法是联合中存储指向不同成员的指针而不是直接存储成员本身。所有指针的长度是相同的,这样就解决了内存浪费的问题。
typedef struct
{
int cost;
int supplier;
}PARTINFO;
typedef struct
{
int n_parts;
struct {
char partno[10];
short quan;
}*parts;
}SUBASSYINFO;
struct INVREC
{
char partno[10];
int quan;
enum {PART, SUBASSY} type;
union {
PARTINFO *part;
SUBASSYINFO *subassy;
}info;
};
struct INVREC rec;
int y, z;
if (rec.type == PART)
{
y = rec.info.part->cost;
z = rec.info.part->supplier;
}
else
{
y = rec.info.subassy->n_parts;
z = rec.info.subassy->parts->quan;
}