C语言 联合体

联合体的声明和结构体类似,但他的行为却和结构体不同。联合体所有成员引用的是内存中相同位置。当你想在不同时刻把不同东西存在同一个位置时可以使用联合体。
看一个简单的例子。

union {
	float f;
	int i;
}fi;

fi.f = 3.14159;
printf("fi.i = %d\n", fi.i);

在一个浮点型和整形都是32位的机器上,变量fi只占据内存中一个32位字,当f被使用时,这个字就作为浮点型值被访问;单i被使用时,这个字就作为整形值被访问。简单说就是同一块内存,被翻译成不同类型的数据,如何翻译取决于定义的数据类型。
上面程序运行结果。

fi.i =  1078530000

联合体的作用

为什么使用联合体,当你只想看浮点型数如何存储在一种特定的机器上,但对其他类型不感兴趣时,联合体可能适合你。看一个例子。

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];
};

接下来的存货(inventory)记录了包含每个项目的一般信息,包括一个联合,或者用于存储零件信息,或者用于存储转配件信息。

struct INVREC {
	char partno[10];
	int quan;
	enum {PART, SUBASSY} type;
	union {
		struct PARTINFO part;
		struct SUBASSYINFO  subassy;
	}info;
};

在一个成员长度不同的联合体里,分配给联合体的内存数量取决于最大成员长度。如果这些成员长度相差悬殊,当存储长度较短成员时会浪费内存,在这种情况下更好的方法是在联合体重存储指向不同成员的指针,而不是存储成员本身。所有指针的长度都是相同的,这样就解决内存浪费的问题。当决定存储那个成员时,分配正确数量的内存来存储该成员。

联合的初始化

联合变量可以被初始化,但这个初始值必须是联合的第一个成员的类型,而且它必须位于一对花括号内。例如,

union {
	int   a;
	float  b;
	char   c[4];
}x = {5};

x.a 初始化为5.
我们不能把这个变量初始化为一个浮点型或者字符值。如果给出的类型是任何其他类型的值,会被强制转化为整型并赋值给x.a。

  • 10
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值