联合体 UNION
目录联合体基础概念联合体内存行为与数据覆盖物联网 / 嵌入式实战用途联合体的坑点与限制总结联合体基础概念联合体共用体关键字union。核心本质联合体内部所有成员共享同一块内存空间。这是和结构体最根本的区别struct每个成员拥有独立内存内存累加会做内存对齐填充。union全部成员共用同一块起始地址同一时刻只能有效使用其中一个成员。cunion Data{ char c; int i; };内存大小规则联合体占用内存 联合体中最大成员的大小同时要满足内存对齐要求。表格类型内存特点struct成员内存相互独立空间相加union全部成员共用同一块起始内存空间复用粗体重点修改联合体其中一个成员的值会覆盖其他成员的数据因为内存重叠。问题Q1联合体所有成员内存地址是相同还是不同Q2联合体的整体占用内存大小由什么决定Q3结构体和联合体哪一个会复用内存空间1.相同2.最大大小的成员3.联合体答案核对✅相同联合体全部成员起始地址完全一致✅由最大的那个成员决定同时还要满足内存对齐约束✅联合体是内存复用结构体成员各自独立占用内存补充小细节不只是简单取最大成员字节数最终联合体总大小还必须是联合体内部最大对齐粒度的整数倍。 举个例子cunion U{ char arr[5]; int num; };最大成员是char arr[5]占 5 字节最大对齐粒度为 int 的 4 字节。 联合体总大小要向上对齐到 4 的倍数最终为8 字节而不是 5 字节。联合体内存行为与数据覆盖联合体所有成员共享同一块内存写入一个成员会直接覆盖这块内存其他成员的数据就被破坏。c#include stdio.h union Test{ int ival; char cval[4]; }; int main(void) { union Test u; u.ival 0x12345678; printf(%02x %02x %02x %02x\n,u.cval[0],u.cval[1],u.cval[2],u.cval[3]); return 0; }在小端机器上运行输出78 56 34 12关键现象解析给ival赋值整数通过cval数组就可以按字节拆开读取。如果接着执行u.cval[0] 0xaa;ival的值会直接被篡改。❗同一时间只保证一个成员有效不要同时读写多个成员属于类型双关部分编译器会有警告。表格操作后果对成员 A 赋值改写共享内存成员 B、C 原有数据失效读取未赋值的成员读出乱码属于未定义行为粗体重点联合体不是同时存放多份数据只是提供多种视角去查看同一块内存。问题Q1向联合体其中一个成员赋值其他成员原有数据会发生什么Q2小端机器union Test中ival0x12345678cval[0]的值是多少Q3联合体读取一个从未赋值过的成员会得到什么结果1.被覆盖2.783.出现乱码答案核对✅被覆盖共享内存被改写其余成员原有数据失效✅0x78小端模式低字节存低地址✅乱码属于 C 标准里的未定义行为结果不可预测补充重要提醒这种用联合体做类型双关int 和 char [] 互相看内存在 C 语言是允许但 C 标准是未定义行为。 物联网单片机STM32C 环境大量这么写用来解析通信报文。物联网 / 嵌入式实战用途联合体在物联网、STM32 开发中不是玩具两个最经典落地场景大小端检测、通信报文解析。场景 1检测大小端cunion EndianCheck{ unsigned int val; unsigned char byte; };小端val0x00000001则byte 0x01大端val0x00000001则byte 0x00场景 2通信报文解析和柔性数组搭配设备串口、CAN 总线收到一帧原始字节流直接映射联合体不用手动移位拼接。ctypedef union { struct{ uint16_t len; uint16_t cmd; uint8_t payload[]; //柔性数组不定长载荷 }frame; uint8_t raw_buf[64]; }MsgUnion;把收到的原始字节数组直接丢进raw_buf就可以直接用.frame.len、.frame.cmd访问报文字段。表格嵌入式场景联合体作用判断 CPU 大小端✅快速检测字节序串口 / CAN 报文解析✅原始字节流 ↔ 结构体直接映射寄存器位拆分✅把 32 位寄存器拆成高低 16 位访问粗体重点网络协议是大端字节序STM32 单片机大多是小端联合体常用来辅助做字节序转换。⚠️注意频繁使用联合体映射报文一定要注意内存对齐对齐填充会直接导致报文解析错乱问题Q1STM32 单片机一般是大端还是小端Q2联合体映射通信报文什么因素会造成解析出来的数据错乱Q3联合体搭配柔性数组主要用来处理什么类型的数据1.小端2.内存对齐不对3.原始字节数组答案核对✅小端全部 STM32 系列 CPU 均为小端模式。✅内存对齐填充结构体内部自动填充的多余字节会让报文字段偏移错位解析乱码。补充写通信报文结构体需要用编译器指令__attribute__((packed))取消对齐填充。✅原始字节数组把收到的字节缓冲区和报文结构体做内存映射直接解析不定长报文。拓展实操小知识点c// 取消结构体对齐填充用于通信报文 typedef struct __attribute__((packed)){ uint16_t len; uint16_t cmd; }Frame;不加packed编译器会自动插入 padding线上报文直接解析失败这是嵌入式非常经典的坑。联合体的坑点与限制联合体用起来很方便但嵌入式 C 里存在大量容易踩的隐性问题写 STM32 通信驱动时经常出错。cunion Danger{ char str[8]; int num; };主要陷阱整理类型双关风险通过联合体用不同成员访问同一块内存C 语言允许但不要跨类型随意读写读出的值属于未定义行为。不能直接整体赋值比较联合体变量可以整体赋值但不能直接用、!做联合体整体比较编译器不支持需要自己逐个成员比对。不能存放带构造的成员C 语言无影响C 要避开对齐带来的额外空间联合体大小不一定等于最大成员会向上对齐到最大对齐成员的整数倍会产生尾部填充字节。表格坑点现象解决办法结构体 padding 带入 union报文偏移错位__attribute__((packed))压缩结构体读写不同成员得到乱码保证同一时刻只使用一个有效成员联合体直接比较编译报错手动逐个字段对比粗体重点__attribute__((packed))只对结构体生效不能给联合体本身去填充联合体内部嵌套的结构体才需要加 packed。问题Q1联合体变量能不能直接使用运算符做整体相等比较Q2联合体内部嵌套结构体为了消除 paddingpacked应该加在谁身上Q3联合体尾部多出的填充字节会对通信报文带来什么影响1.不能2.结构体3.报错答案核对✅不能C 语言不支持联合体直接用整体比较需要手动逐个成员对比。✅加在联合体内部嵌套的结构体上packed对 union 本身无效。⚠️不完全准确尾部填充字节本身不会直接报错但是填充的无效垃圾字节会混入报文缓冲区造成接收方解析出来数据错乱逻辑出错不一定直接程序崩溃。补充 当联合体内部结构体没有packed结构体自带 padding这部分 padding 字节会进入联合体共享内存发送出去之后对方设备按协议解析字段偏移全部错位。总结至此联合体全部内容完成把整套知识和你物联网专业串联复盘。核心总览表格项目struct 结构体union 联合体内存模型每个成员独立内存空间累加全部成员共享同一块起始内存内存复用总大小所有成员大小总和 对齐填充取最大成员大小再对齐到最大对齐粒度倍数使用场景描述一组并存的属性内存视角转换、大小端检测、通信报文解析嵌入式坑padding 填充破坏通信帧类型双关、内部结构体 padding、不能整体比较c//物联网典型完整示例packed结构体嵌套在union搭配柔性数组做通信报文 typedef union { struct __attribute__((packed)){ uint16_t len; uint16_t cmd; uint8_t payload[]; } frame; uint8_t buf[64]; } PacketUnion;粗体重点联合体本质同一块内存多种解释视角同一时刻仅一个成员有效。和你前面学的结构体对齐、柔性数组、位域共同构成 C 嵌入式内存四大板块写 STM32 驱动、竞赛报文解析高频使用。开发报文时__attribute__((packed))施加在内部结构体消除 padding避免报文错位。

相关新闻

模型自动化与人类增强未必相关:Agent提效评测的误区与对策

模型自动化与人类增强未必相关:Agent提效评测的误区与对策

同一个大模型 Agent,在不同人手里的效果差距可以很大。有人让它接管周报、SQL、接口自动化脚本,个人产出明显提升;有人试用两周后把插件卸载,理由是“它总能一本正经地给出错误答案”。更让人觉得拧巴的是评测侧:某个模…

2026/10/31 13:28:10 阅读更多 →
用友校招Java笔试题复盘:基础原理与工程实践全解析

用友校招Java笔试题复盘:基础原理与工程实践全解析

1. 这套卷子的命题逻辑:用友校招Java笔试到底在筛什么样的人 先说一个很多人容易误解的地方:用友这类做ERP、财务软件、云服务起家的ToB公司,校招笔试和互联网大厂笔试的筛选逻辑其实不太一样。互联网大厂喜欢用算法题海选,动辄Ha…

2026/11/10 0:44:36 阅读更多 →
MIT 6.0001:用计算思维连接数学与Python编程

MIT 6.0001:用计算思维连接数学与Python编程

有一类困惑特别典型:Python 语法书翻了大半,列表、字典、循环、函数都能写,可一遇到“用程序解一道数学题”或者“把一个递推公式做成可运行代码”的任务,大脑立刻空白。我最初接触 MIT 6.0001《计算机科学导论》时,就…

2026/11/5 11:24:03 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/13 5:13:25 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/13 5:13:25 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/13 5:13:25 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/12 18:22:26 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/12 18:22:25 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/13 5:13:25 阅读更多 →

日新闻

周新闻

月新闻