一句话:"struct 各自有房(累加),union 共住一室(取最大)——struct 存同时需要的,union 存轮流用的。"
struct 成员依次排开、各自独立;union 所有成员共用同一块内存。判别核心 = 成员"同时用还是轮流用"。union 三大用途:测大小端、省内存的变体消息、寄存器字节/字复用。
struct S { char c; int i; }; → c、i 独立,sizeof = 8(含填充)union U { char c; int i; }; → 共用同一地址,写 i 覆盖 c,sizeof = 4(最大成员)union { int i; char c; } u; u.i = 0x12345678; u.c == 0x78 → 小端;0x12 → 大端(c 和 i 共用起始地址,读 c 看到最低字节)union { struct A{...}; struct B{...}; uint8_t raw[6]; } → 不同协议共用一块 buffer,统一按 raw 收发再按 id 解析| struct | union | |
|---|---|---|
| 存储 | 依次排开,各自独立 | 共用一块,同一时刻用一个 |
| 大小 | 成员之和 + 填充 | 最大成员 |
| 写一个成员 | 不影响其他 | 覆盖其他成员 |
| 典型用途 | 组合数据 | 省内存、变体消息、大小端判断 |
大小端 = 多字节数据在内存里的排列顺序。int i = 0x12345678:
| 低地址字节 | 内存里看到 | 谁在用 | |
|---|---|---|---|
| 小端 little-endian | 存低字节 78 |
78 56 34 12 |
x86、ARM 主流 |
| 大端 big-endian | 存高字节 12 |
12 34 56 78 |
网络协议、某些 CPU |
union 原理:所有成员共享同一起始地址。u.i = 0x12345678 后读 u.c(char 取一字节)= 最低地址字节 → 小端给 0x78、大端给 0x12。跨平台通信必须约定字节序,否则 A 存的低字节 B 按大端解读就变值了。
union { char c; short s; int i; }; → sizeof = 4(最大成员 int)union { int i; double d; }; → sizeof = 8(double 最大且对齐 8)u.i = 10; 后再 u.c = 'a'; → u.i 不可靠(写 c 覆盖了 i 的内存)78 56 34 12),大端反之;x86/ARM 主流小端,网络协议常大端。union 测法:u.i=0x12345678; 看 u.c 是 0x78 还是 0x12| 相邻概念 | 和本主题的关系 | 孤立理解会犯的错 |
|---|---|---|
| 结构体对齐 | 大小计算同一套规则:union 大小 = 最大成员(含其对齐) | 以为 union 也像 struct 累加 |
| 大小端 | union 测大小端的原理 = 共用起始地址看最低字节 | 不懂字节序就看不懂 union 的这个用途 |
| 位域 | 都是压缩内存的手段 | 以为 union 和位域只能二选一 |
| 通信协议 | 变体消息:struct 封装各协议 + union 统一 buffer | 不用 union 每个协议各开一块 buffer 浪费内存 |
2026-08-03
每主题一页,复习时只翻本目录。