网站开发最强工具,凡科互动h5,四川住房建设厅网站首页,wordpress无法访问图片联合体#xff08;Union#xff09;简介
联合体#xff08;union#xff09;是 C 和 C 编程语言中的一种数据结构#xff0c;和结构体#xff08;struct#xff09;类似#xff0c;但有一些重要的区别。
定义
联合体中的所有成员共享同一段内存#xff0c;也就是说…联合体Union简介
联合体union是 C 和 C 编程语言中的一种数据结构和结构体struct类似但有一些重要的区别。
定义
联合体中的所有成员共享同一段内存也就是说联合体中的多个成员变量会占用相同的地址但是在任何一个时间点只能存储一个成员的值。 1. 联合体的定义和语法
定义语法
union UnionName {DataType member1;DataType member2;...
};示例
union Example {int i; // 整数占用 4 字节float f; // 浮点数占用 4 字节char c; // 字符占用 1 字节
};这里的联合体 Example 包含了 3 个成员 一个整数 i占用 4 字节。一个浮点数 f占用 4 字节。一个字符 c占用 1 字节。 存储特点 联合体的总大小取决于它的最大成员所需的内存大小这里是 4 字节因为 int 和 float 都占 4 字节。 2. 联合体的内存分配
内存共享特点
联合体中的所有成员都共享同一块内存因此 写入一个成员会覆盖其他成员的值。在任意时刻联合体中只能存储一个有效值。
示例
union Example {int i; // 整数占用 4 字节float f; // 浮点数占用 4 字节char c[4]; // 字符数组占用 4 字节
};
union Example ex;
ex.i 42; // 写入整数 42
printf(i: %d\n, ex.i); // 输出 i 的值42
ex.f 3.14; // 写入浮点数 3.14
printf(f: %.2f\n, ex.f); // 输出 f 的值3.14
printf(i: %d\n, ex.i); // 输出 i 的值此时 i 的值已被覆盖输出
i: 42
f: 3.14
i: 1078523331 // i 的值被 f 的写入覆盖解释为浮点数的二进制形式3. 联合体的用途
3.1 内存节省
联合体非常适合需要节省内存的场景。由于多个成员共享同一段内存可以显著减少内存占用。
3.2 数据转换
联合体常用于类型转换允许以不同的方式访问同一块数据。
示例浮点数与二进制表示的转换
#include stdio.h
union FloatToBits {float f;unsigned int bits;
};
int main() {union FloatToBits data;data.f 3.14; // 写入浮点数printf(Float: %.2f\n, data.f); // 输出浮点数printf(Bits: 0x%X\n, data.bits); // 输出二进制表示return 0;
}输出
Float: 3.14
Bits: 0x4048F5C3同一块内存可以通过 data.f 访问为浮点数通过 data.bits 访问为其二进制位。 4. 联合体的常见用途
4.1 数据协议处理
联合体常用于解析二进制数据流。例如在通讯协议中可以通过联合体将字节流解析为特定的数据结构。
示例解析 16 位数据的高低字节
union Data16 {unsigned short full; // 16 位数据struct {unsigned char low; // 低字节unsigned char high; // 高字节} parts;
};
int main() {union Data16 data;data.full 0x1234; // 写入 16 位数据printf(Full: 0x%X\n, data.full); // 输出完整值printf(High: 0x%X\n, data.parts.high); // 输出高字节printf(Low: 0x%X\n, data.parts.low); // 输出低字节return 0;
}输出
Full: 0x1234
High: 0x12
Low: 0x34应用场景
网络协议 在网络通讯中经常需要解析协议头部例如 IP 包头、TCP 包头等联合体可以方便地拆解字段。 嵌入式开发 在嵌入式系统中用联合体将字节序列解析为多字节变量如 int 或 float。 4.2 硬件寄存器操作
联合体可以用于操作硬件寄存器通过联合体直接访问寄存器的特定位。
示例32 位寄存器的分段访问
union Register {unsigned int value; // 寄存器的完整值struct {unsigned char byte0; // 第 0 字节unsigned char byte1; // 第 1 字节unsigned char byte2; // 第 2 字节unsigned char byte3; // 第 3 字节} bytes;
};
int main() {union Register reg;reg.value 0x12345678; // 写入寄存器值printf(Byte 0: 0x%X\n, reg.bytes.byte0); // 输出低字节printf(Byte 1: 0x%X\n, reg.bytes.byte1); // 输出次低字节printf(Byte 2: 0x%X\n, reg.bytes.byte2); // 输出次高字节printf(Byte 3: 0x%X\n, reg.bytes.byte3); // 输出高字节return 0;
}输出
Byte 0: 0x78
Byte 1: 0x56
Byte 2: 0x34
Byte 3: 0x125. 联合体与结构体的区别
特性联合体union结构体struct内存分配所有成员共享同一段内存大小由最大成员决定每个成员都有独立的内存大小是所有成员内存之和成员访问同一时刻只能存储一个成员访问其他成员可能导致数据不一致所有成员可以同时访问互不干扰用途内存节省数据转换多种数据形式的联合表示表示多种属性的组合体使用限制不适合需要同时使用多个成员的场景可以同时访问多个成员 6. 注意事项
数据覆盖 由于所有成员共享内存当你写入一个成员时会覆盖其他成员的值。使用联合体时要非常小心确保对成员的访问逻辑正确。 对齐与大小 联合体的大小由其最大成员的大小决定并可能受到编译器对齐padding的影响。 联合体与类型安全 联合体没有类型检查机制读写不同类型的成员时可能导致不安全行为。 7. 总结
联合体是 C/C 中的一种高级数据类型适用于节省内存、数据解析和类型转换等场景。其核心特点是成员共享同一段内存这既带来了灵活性也对程序员提出了更高的使用要求。常见用途包括 数据协议解析如解析高低字节。硬件寄存器操作。浮点数与二进制位的转换。节省内存空间的场景。
如有侵权联系删除