位域允許在結構體中按位分配成員,節省記憶體,常用於:硬件寄存器映射、網絡協議頭部、標誌位組合、壓縮數據存儲。
struct BitField {
unsigned int a : 8; // 佔 8 位
unsigned int b : 2; // 佔 2 位
unsigned int c : 6; // 佔 6 位
}; // 共 16 位 = 2 字節
int、unsigned int、signed int(C99 允許 _Bool),位寬不得超過類型位寬(通常 32 位)。unsigned int : 0 強制對齊。unsigned int : 2;&bf.a 非法,因位域可能不按字節對齊。struct Demo {
unsigned int a : 4; // bits 0-3
unsigned int : 0; // 強制對齊到下一 int
unsigned int b : 4; // bits 0-3 of next int
unsigned int c : 4; // bits 4-7 of next int
}; // 佔 8 字節(兩個 int)
#include <stdio.h>
struct Status {
unsigned int power : 1; // 0/1
unsigned int mode : 2; // 0-3
unsigned int speed : 3; // 0-7
unsigned int reserved: 2; // 填充
unsigned int error : 1; // 0/1
}; // 共 9 位,實際佔 4 字節
int main() {
struct Status dev = {1, 2, 5, 0, 0}; // power=1, mode=2, speed=5
printf("Size: %zu bytes\n", sizeof(dev)); // 4
printf("Power: %u, Mode: %u, Speed: %u\n", dev.power, dev.mode, dev.speed);
// 位運算操作
dev.speed &= 3; // 限制速度 0-3
dev.error |= 1; // 置錯誤位
printf("After: Speed=%u, Error=%u\n", dev.speed, dev.error);
// 指針操作(針對整個結構體)
struct Status* p = &dev;
p->mode = 3;
return 0;
}
| 差異點 | 可能行為 | 建議 |
|---|---|---|
| 位域分配順序 | GCC/MSVC 通常從低位到高位;某些嵌入式編譯器反向 | 避免依賴具體位偏移,或用條件編譯 |
| 基礎類型大小 | 16/32/64 位系統 int 寬度不同 | 显式使用 uint32_t 等固定寬類型 (C99 <stdint.h>) |
| 有符號位域 | 負值表示實現定義(補碼/反碼/符號幅度) | 優先用 unsigned,除非明確需要負值 |
| 結構體大小/對齊 | 受 #pragma pack、編譯器默認對齊影響 | 用 static_assert(sizeof(Struct)==N) 驗證 |
bool,單字節存 8 個開關。std::bitset<N>:編譯期固定大小,提供豐富位運算,類型安全。std::vector<bool>:動態位向量,專用迭代器,但非標準容器(代理引用)。GET_BIT(x, n)、SET_BIT(x, n),完全可控,無編譯器差異。位域是 C 語言節省記憶體、映射硬件的利器,但不可移植性強。嵌入式、驅動開發中慎用並充分測試;應用層開發優先考慮 std::bitset、手動位運算或壓縮結構體(#pragma pack(1))以換取可移植性。