引言
联合体(union)是 C/C++ 中一种特殊的复合数据类型,它允许不同类型的成员共享同一块内存空间,主要用于在有限内存中存储 “互斥使用” 的数据。
一、基本用法
1.1 定义与声明
使用 union 关键字定义联合体,语法与结构体类似,但成员共享内存。
// 定义联合体(存储不同类型的数值,但同一时间仅一种有效)
union Data
{int i; // 整数float f; // 浮点数char c; // 字符
};
// 声明联合体变量
union Data d1; // 方式1:完整声明
Data d2; // 方式2:结合typedef取别名(更简洁)//结合 typedef 取别名(推荐):
typedef union
{int i;float f;char c;
} Data;Data d; // 直接用别名声明,无需重复写union
1.2 成员访问
通过 . 操作符访问成员,与结构体用法一致;若为指针,则用 -> 操作符。
#include <stdio.h>typedef union
{int i;float f;char c;
} Data;int main()
{Data d;// 赋值整数成员d.i = 100;printf("d.i = %d\n", d.i); // 输出 100// 此时访问其他成员会得到乱码(内存被覆盖)printf("d.f = %f\n", d.f); // 输出无意义值(如 0.000000 或随机数)// 赋值浮点数成员(覆盖整数的内存)d.f = 3.14f;printf("d.f = %f\n", d.f); // 输出 3.140000printf("d.i = %d\n", d.i); // 输出浮点数3.14的二进制对应的整数值(乱码)return 0;
}
1.3 内存特性
- 所有成员共享同一块内存,起始地址相同。
- 联合体的大小 = 最大成员的大小(确保能容纳所有成员中最大的那个)。
二、应用场景
2.1 解析二进制数据(内存共用)
例如解析一个 4 字节的二进制数据,既可视为整数,也可视为浮点数:
// 4字节二进制数据,可按int或float解析
typedef union
{int i;float f;char bytes[4]; // 按字节访问
} BinaryData;int main()
{BinaryData data;data.i = 0x41480000; // 二进制值printf("作为整数:%d\n", data.i); // 输出 1094060032printf("作为浮点数:%f\n", data.f); // 输出 12.5(0x41480000对应float的12.5)printf("字节1:%02X\n", data.bytes[0]); // 输出 00(小端存储)return 0;
}
三、注意事项(避坑关键点)
3.1 成员互斥,赋值会覆盖
写入一个成员会覆盖其他成员的内存,读取未被赋值的成员会得到无意义的 “脏数据”。
解决:始终用一个 “类型标记”(如枚举)记录当前有效的成员类型(见场景 1 示例)。
3.2 内存对齐规则
联合体的大小由最大成员决定,但需满足最大成员的对齐要求:
union Align
{char c; // 1字节(对齐要求1)double d; // 8字节(对齐要求8)
};
printf("联合体大小:%lu\n", sizeof(union Align)); // 输出8字节(满足double的对齐)