C语言共用体
👇😊 C语言共用体(Union) 😊👇
🌈 1. 共用体是什么?
现在你有一个多功能储物箱🎁,同一时间只能放一种物品(比如书、水杯或零食),但箱子会根据物品自动调整内部空间。共用体(Union)就是这样的“箱子”:
- 特点:所有成员共享同一块内存,同一时间只能使用一个成员!
- 目的:节省内存,灵活处理不同类型数据(但不能同时存储)
🌈 2. 共用体 vs 结构体:关键区别
| 共用体(Union) | 结构体(Struct) | |
|---|---|---|
| 内存分配 | 所有成员共享同一块内存 | 每个成员有独立内存 |
| 内存大小 | 等于最大成员的大小 | 等于所有成员大小之和(考虑对齐) |
| 使用场景 | 同一时间只存一种类型数据 | 同时存储多个类型数据 |
🌈 3. 共用体的定义与内存分配
3.1 定义共用体
📝 语法:
1 | union 共用体标签 { |
🌰 例子:
1 | union Data { |
3.2 内存大小验证
1 | printf("共用体大小:%zu\n", sizeof(union Data)); // 输出20 |
🌈 4. 共用体成员访问
4.1 基本访问
使用 . 运算符访问成员(与结构体相同):
1 | data.i = 10; // 存入整数 |
4.2 重要特性
- 内存共享:修改一个成员会覆盖其他成员的值!
- 同一时间只能用一种成员,否则数据会混乱!
🌰 错误示例:
1 | data.i = 10; |
✅ 正确用法:
1 | data.i = 10; |
🌈 5. 共用体的应用场景
- 节省内存:处理多个类型数据但不同时使用的情况
- 如:嵌入式设备中,根据模式存储温度(float)或状态码(int)
- 解析不同数据格式
- 如:网络协议中,同一字段可能是IP地址(字符串)或错误码(整数)
- 类型转换黑科技
- 通过共用体直接将整数的内存解释为浮点数(谨慎使用!)
🌰 类型转换示例:
1 | union Converter { |
🌈 6. 共用体的初始化
共用体只能初始化第一个成员:
1 | union Data data = {10}; // 正确 → 初始化i为10 |
其他成员需后续赋值:
1 | data.f = 3.14; // 正确,但会覆盖i的值 |
🌈 7. 共用体与结构体嵌套
共用体可以作为结构体的成员,反之亦然。
🌰 例子:根据数据类型存储不同信息
1 | struct SensorData { |
🌈 8. 常见错误与避坑指南
同时使用多个成员
1
2
3
4union Data data;
data.i = 10;
data.f = 3.14; // i的值被覆盖!
printf("%d", data.i); // 输出错误数据 ❌未初始化直接使用
1
2union Data data;
printf("%d", data.i); // 随机值!可能引发问题 ❌错误计算内存大小
1
2
3
4
5union Data {
int i;
double d; // 8字节 → 共用体总大小=8
};
printf("%zu", sizeof(union Data)); // 正确输出8 ✅
🌈 9. 综合练习
练习1:类型转换器
用共用体实现一个整数和浮点数的互相转换器,验证内存共享特性。
练习2:协议解析
定义一个共用体 Packet,包含整数ID、浮点数值和字符串消息,根据类型字段解析数据。
练习3:错误修复
以下代码有什么问题?
1 | union Value { |
🎯 参考答案
练习1:
1 |
|
练习2:
1 |
|
练习3:
问题:存入字符串后,整数成员 num 的值被覆盖,输出的是字符串的内存解释值(垃圾值)。
修正:确保同一时间只使用一个成员!
🚀 总结:
- 共用体是“内存共享大师”,节省内存但需谨慎使用!
- 同一时间只能激活一个成员,否则数据会“打架”!
- 适合处理类型多变但不同时使用的数据场景
记住:多动手写代码,感受内存共享的神奇与陷阱! 💻🔧
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Matou🚢!
评论


