在C语言中,共用体(Union),也称为联合体,是一种特殊的数据类型,允许在相同的内存位置存储不同的数据类型。
1. 定义与语法
共用体的定义方式与结构体(struct)类似,使用 union 关键字:
bash
// 先定义模板,再声明变量
union Data {
int i;
float f;
char str[20];
};
// 定义模板的同时声明变量
union Data {
int i;
float f;
} data1, data2;
// 使用 typedef 起别名
typedef union {
int i;
float f;
} Value;
Value v1; // 直接使用别名声明
2. 调用与访问方式
2.1、 访问成员(使用点运算符 .)
这是最直接的访问方式,用于普通的共用体变量。
2.2、通过指针访问(使用箭头运算符 ->)
当使用指向共用体的指针时,必须使用 ->。
bash
union Data data;
union Data *ptr = &data;
ptr->i = 100; // 等价于 (*ptr).i = 100;
printf("%d", ptr->i);
2.3、初始化方式
共用体在初始化时,通常只能初始化它的第一个成员。
bash
union Data data = {10}; // 正确:初始化了第一个成员 i
// union Data data = {10, 2.5}; // 错误:共用体不能同时初始化多个成员
在 C99 标准中,可以使用"指定初始化器"来初始化特定成员:
bash
union Data data = {.f = 1.23f};
3. 核心特点
共享内存:共用体中的所有成员都从同一个内存地址开始存储。
内存占用:共用体占用的内存大小等于其最大成员的大小(有时需要考虑内存对齐)。
互斥使用:在同一时刻,只能存储和使用其中一个成员的值。给一个新成员赋值会覆盖掉之前成员的值。
4. 共用体 vs 结构体
| 特性 | 结构体 (struct) | 共用体 (union) |
|---|---|---|
| 内存分配 | 每个成员都有独立的内存空间 | 所有成员共享同一块内存空间 |
| 总大小 | 所有成员大小之和(含对齐) | 最大成员的大小(含对齐) |
| 成员访问 | 可同时访问所有成员 | 同一时间只能有效访问一个成员 |
5. 代码示例
bash
#include <stdio.h>
#include <string.h>
union Data {
int i;
float f;
char str[20];
};
int main() {
union Data data;
printf("Memory size occupied by data: %lu\n", sizeof(data));
data.i = 10;
printf("data.i: %d\n", data.i);
data.f = 220.5;
printf("data.f: %f\n", data.f);
strcpy(data.str, "C Programming");
printf("data.str: %s\n", data.str);
// 此时访问 i 和 f 会得到错误的结果,因为内存已被 str 覆盖
printf("data.i after str: %d\n", data.i);
return 0;
}
6. 主要应用场景
节省内存:当程序中有多个变量但它们不会同时被使用时。
硬件寄存器访问:在嵌入式开发中,常用于将一个长字(word)拆分为多个字节(byte)进行访问。
类型转换(Type Punning):通过共用体观察同一段二进制数据的不同解释方式(例如查看浮点数的位模式)。