聯合體 是一種特殊的構造類型,允許多個不同類型的成員共用同一塊內存區域。任意時刻,只能存儲其中一個成員的值。
union Data {
int i;
float f;
char str[20];
} data; // 定義聯合體變量 data
// 或分離聲明
union Data { int i; float f; };
union Data data;
union {
int i;
struct { char high, low; } bytes;
} converter;
converter.i = 0x4241; // 'B' 'A'
printf("%c%c\n", converter.bytes.high, converter.bytes.low); // 輸出 AB (大端序) 或 BA (小端序)
converter.bytes.high = 'a';
converter.bytes.low = 'b';
printf("%x\n", converter.i); // 輸出 6261 ('b' 'a' 的 ASCII)
應用:網絡字節序轉換、硬件寄存器位域訪問、類型懲罰。
| 特性 | 結構體 | 聯合體 |
|---|---|---|
| 內存佈局 | 成員依次排列,互不重疊 | 成員完全重疊,共用地址 |
| 大小 | 所有成員大小之和(含對齊) | 最大成員大小(含對齊) |
| 同時存活 | 所有成員同時存在 | 僅一個成員有效 |
| 賦值影響 | 互不干擾 | 覆蓋其他成員 |
| 典型用途 | 聚合相關數據 | 節省空間、類型轉換、變長數據 |
struct Packet {
int type;
union {
struct { int x, y; } mouse;
struct { int key; } keyboard;
char raw[64];
} data; // 匿名聯合體 (C11)
};
// 訪問
p.data.mouse.x = 100;
printf("%d\n", p.data.raw[0]); // 查看原始字節
枚舉 定義一組命名的整型常量,增強代碼可讀性與類型安全(編譯器可檢查 switch 覆蓋)。
enum Weekday { SUN, MON, TUE, WED, THU, FRI, SAT };
enum Weekday today = MON;
// 顯式指定值
enum Status { OK = 0, ERR_MEM = -1, ERR_IO = -2, ERR_NET = -3 };
// 後續成員自動 +1
enum Flags { F1 = 1, F2 = 2, F3 = 4, F4 = 8 }; // 位掩碼常用
int(或兼容整型),可隱式轉換。// 魔術數字消除
if (status == ERR_IO) { /* ... */ }
// switch 完整性檢查 (GCC/Clang -Wswitch-enum)
switch (day) {
case MON: case TUE: case WED: case THU: case FRI: work(); break;
case SAT: case SUN: rest(); break;
// 缺少 default,編譯器警告未處理枚舉值
}
| 特性 | #define | enum |
|---|---|---|
| 類型安全 | 無 | 有(編譯器知類型) |
| 調試可見 | 不可見(預處理替換) | 可見(符號表保留) |
| 作用域 | 全局(文件級) | 遵循塊作用域 |
| 分組關聯 | 無 | 強語義分組 |