聯合體 是一種特殊的建構型別,允許在相同記憶體位置儲存不同型別的資料(但同一時間僅能存取其中一個成員)。主要用途:節省記憶體空間、型別雙關、硬體暫存器映射。
union UnionName {
type1 member1;
type2 member2;
// ...
} variable_list;
// 等價於
union UnionName {
type1 member1;
type2 member2;
};
union UnionName var1, var2;
| 特性 | 說明 | 範例 |
|---|---|---|
| 大小由最大成員決定 | sizeof(union) == sizeof(largest_member) (含對齊填充) | union {char c; int i;} → 4 bytes |
| 成員共享記憶體 | 所有成員起始位址相同 (offset = 0) | &u.c == &u.i == &u |
| 同一時間單一有效值 | 寫入新成員會覆蓋舊資料 | u.c='A'; u.i=0x41424344; → c 變 'D' |
| 低位址優先儲存 | 所有成員從低位址開始存放 | 小端序下 int 低位元組對齊 char |
#include#include typedef union { char c; int a; int b; } Demo; int main() { Demo d; d.c = 'H'; // 0x48 d.a = 10; // 覆蓋 c,記憶體: 0x0A 00 00 00 d.b = 12; // 覆蓋 a,記憶體: 0x0C 00 00 00 printf("大小: %zu bytes\n", sizeof(d)); // 4 printf("值: %c\t%d\t%d\n", d.c, d.a, d.b); // L(0x4C) 12 12 // 解析: 12 = 0x0C -> 低位元組 0x0C = 'L' (ASCII 76) return 0; }

union FloatBits {
float f;
uint32_t bits;
struct { uint32_t mantissa:23; uint32_t exponent:8; uint32_t sign:1; } parts;
};
void print_float_bits(float val) {
union FloatBits fb = {.f = val};
printf("0x%08X | sign=%u exp=%u mantissa=%u\n",
fb.bits, fb.parts.sign, fb.parts.exponent, fb.parts.mantissa);
}
union Packet {
struct {
uint16_t header;
uint8_t cmd;
uint8_t len;
uint8_t payload[12];
} fields;
uint8_t raw[16];
};
union State {
struct { uint8_t type; int value; } integer;
struct { uint8_t type; float value; } floating;
struct { uint8_t type; char str[16]; } string;
};
| 維度 | 結構體 | 聯合體 |
|---|---|---|
| 記憶體佈局 | 成員依序排列,位址遞增 | 所有成員位址相同 (offset 0) |
| 大小計算 | 成員大小總和 + 對齊填充 | 最大成員大小 (向上對齊) |
| 同時有效成員 | 全部 | 僅一個 |
| 典型用途 | 資料聚合 | 型別轉換、省空間、硬體映射 |
union U u = {.c = 'A'};聯合體是 C 語言處理「同一記憶體、多種解讀」的利器。精通其記憶體共享機制、大小計算規則與型別雙關技巧,能在嵌入式開發、網路協定解析、高效能資料結構等領域發揮關鍵作用。實務上請配合 static_assert 驗證大小與對齊,並以詳細註釋說明預期用法,避免維護困難。