联合体(Union)与结构体(Struct)在C语言中都是用于组合多种不同类型的数据,但它们在内存分配和使用上有显著的不同。以下是它们之间的主要区别:
1. 内存分配:- 结构体:每个成员都有自己的内存空间,成员之间的内存是连续分配的,结构体的总大小是所有成员大小的总和,加上必要的内存对齐填充。这意味着结构体中的所有成员同时存在于内存中。
- 联合体:所有成员共享同一块内存空间,联合体的大小至少能容纳其最大的成员。这表示,在任意时刻,联合体中只有一个成员的数据是有效的,因为它们都在相同的内存位置上。
2. 数据存储:- 结构体:可以同时存储所有成员的数据,每个成员的修改不会影响其他成员。
- 联合体:同一时间只能存储一个成员的数据,对联合体中的任何一个成员的修改会影响到其他成员,因为它们共享同一块内存。
3. 内存效率:- 结构体:通常占用更多的内存,因为它为每个成员分配独立的空间。
- 联合体:在内存使用上更为紧凑,因为它复用了同一段内存空间给不同的成员。
4. 用途:- 结构体:常用于封装一组相关的数据,如一个人的信息(姓名、年龄、地址等)。
- 联合体:适合于处理多种可能的数据类型,但只需要存储一种类型的情况,比如配置选项或硬件寄存器的设置,其中可能需要不同的数据类型来表示不同的功能。
5. 初始化:- 结构体:可以初始化所有成员。
- 联合体:通常只能初始化一个成员,因为它们共享相同的内存空间。
这里有一个简单的示例来说明结构体和联合体的区别:
#include <stdio.h>
#include <string.h>
struct MyStruct {
int i;
float f;
char str[20];
};
union MyUnion {
int i;
float f;
char str[20];
};
int main() {
struct MyStruct s;
union MyUnion u;
s.i = 10;
s.f = 3.14f;
strcpy(s.str, "Hello Struct");
u.i = 10; // 写入整数值
printf("Union Integer Value: %d\n", u.i);
u.f = 3.14f; // 覆盖之前的整数值
printf("Union Float Value: %f\n", u.f);
strcpy(u.str, "Hello Union"); // 覆盖之前的浮点数值
printf("Union String Value: %s\n", u.str);
return 0;
}
在这个例子中,`MyStruct`结构体在内存中为每个成员分配了独立的空间,而`MyUnion`联合体中的成员共享同一块内存,因此,对联合体中成员的每一次赋值都会覆盖前一个成员的值。