位域允許在結構體中指定成員佔用的精確位數,適用於硬件寄存器映射、網絡協議頭部、標誌位壓縮等場景。
typedef struct ST_TIME {
DWORD second : 6; // 0-59 (6 位可表示 0-63)
DWORD minute : 6; // 0-59
DWORD hour : 5; // 0-23 (5 位可表示 0-31)
DWORD day : 5; // 1-31
DWORD month : 4; // 1-12 (4 位可表示 0-15)
DWORD year : 6; // 0-63 (對應 2000-2063)
} TIME; // 總計 32 位 = 4 字節
int、unsigned int、signed int),C99 允許 _Bool。&time.second 非法,位域不佔用獨立內存地址。signed/unsigned 時,int 位域符號性實現定義,建議顯式聲明 unsigned。volatile 使用,定義精確匹配數據手冊的位域結構。struct Flags { unsigned f1:1, f2:1, f3:1; }; 替代多個 bool 節省空間。C 語言結構體無構造函數,但可通過設計模式實現聲明即初始化:
typedef struct ST_INFO {
DWORD32 cnt;
BYTE time[1024];
} INFO;
// 初始化函數
static inline void INFO_Init(INFO *p) {
p->cnt = 0;
memset(p->time, 0, sizeof(p->time));
}
// 宏模擬「聲明即初始化」
#define INFO_DECLARE(name) INFO name = {0} // C99 指定初始化器更佳
// 或 GCC 擴展:INFO name = { .cnt=0, .time={0} };
// 直接聲明並完全初始化
INFO my_info = {
.cnt = 0,
.time = {0} // 柔性數組/固定數組均可
};
// 部分初始化,其餘自動歸零
INFO another = { .cnt = 42 };
void process_info(INFO *p);
int main() {
// 臨時對象傳遞給函數,無需命名變量
process_info(&(INFO){ .cnt = 10, .time = {0} });
return 0;
}
| 技巧 | 適用場景 | 優點 | 注意事項 |
|---|---|---|---|
| 位域 | 硬件寄存器、標誌位壓縮、協議頭 | 極致節省內存、硬件映射直觀 | 不可移植、無法取址、符號性陷阱 |
| 指定初始化器 | 所有結構體聲明 | 標準、可讀、安全、部分初始化自動歸零 | 需 C99 支持(現代編譯器均支持) |
| 複合字面量 | 臨時參數、鏈表節點創建 | 減少臨時變量、代碼緊湊 | 生命週期為當前塊,不可返回指針 |