C语言中联合union的正确用法。

##C语言中联合union的正确用法。

假设你想用结构来模拟某样东西。但这个东西的属性可以用多种的数据类型来表示。

例如,一箱苹果你可以几种数据类型来表示:

  • 1、一箱有10个苹果。(int)
  • 2、一箱有2.5斤苹果。(float)
  • 3、一箱有1.25公斤苹果。(float)

如果使用常规的结构体来表示的话:

typedef struct {
	int number; // 苹果个数 4字节
	float weight_half_KG; // 苹果重量(斤) 4字节
	float weight_KG; // 苹果重量(公斤) 4字节
}Apple;

这不是一个好主意,因为结构体在内存中占用了更多的空间(结构体Apple占用了12个字节),无论用户是只使用了一个字段,还是三个字段都使用了。用户可能会既设置一箱苹果的数量,也设置了重量。

因此,我们会自然而然的想,如果有一种数据类型,可以根据我给出的数据来决定是使用何种数据类型就好了。当我给出的是整形数据,那就使用“int number”;如果我给出的是浮点数数据,根据需要使用“float weight_half_KG”或“float weight_KG”。而C语言中的联合就可以做到这点。

当定义联合时,计算机会为根据其中最大的字段分配空间。

typedef union {
	int number; // 苹果个数 4字节
	float weight_half_KG; // 苹果重量(斤) 4字节
	float weight_KG; // 苹果重量(公斤) 4字节
}Apple;

在这里三个字段的都是4字节,因此计算机会分配4字节的内存空间给我们定义的联合变量使用。无论是设置了number,还是weight_half_KG,还是weight_KG,他们都会保存在内存中的同一个地方。而且长度只有4个字节。

我们可以使用整形的变量:

int main()
{
	Apple a;
	a.number = 10;  // 一箱苹果有10个
}

我们也可以使用浮点数的变量:

int main()
{
	Apple a;
	a.weight_half_KG= 2.5; // 一箱苹果有2.5斤
}

获取联合成员的方式和获取结构成员的方式一。唯一的差异在于,当改变一个联合成员的值时,实际上修改了该联合所有成员的值。

int main()
{
	Apple a;
	a.weight_KG= 1.25; // 一箱苹果有1.25公斤

	printf("%p\n", &a.number);
	printf("%p\n", &a.weight_half_KG);
	printf("%p\n", &a.weight_KG);
}

联合中的所有字段都可以访问,但它们会指向同一个地址。只是它们在使用时表现的数据类型不一样。

计算机需要保证联合的大小固定。唯一的办法就是使用最大的内存,让任何一个字段都装得下。如果定义的时候没有指定初始化,会被隐式地初始化为0值

联合提供了一种方法,一种可以用不同数据类型创建变量的方法。而且联合经常会和结构体一起使用。