位段(Bit-field)是 C 語言中一種特殊的結構體(或聯合體)成員定義方式,它允許開發者以位(bit)為單位精確控制成員變數佔用的儲存空間。包含位段的結構體稱為位段結構。合理使用位段結構,不僅能有效節省記憶體空間,還能方便進行底層位操作,常見於嵌入式系統、網路協定解析、硬體暫存器映射等場景。
位段成員的宣告格式如下:
type [member_name] : width;
int、unsigned int、signed int 三種類型之一。關於 int 是否預設為有號,視編譯器而定(例如 MSVC 預設 int 為 signed int)。int 通常為 32 位)。struct node {
unsigned int a : 4; // 位段 a,佔 4 位
unsigned int : 0; // 無名位段,寬度為 0(特殊對齊用途)
unsigned int b : 4; // 位段 b,佔 4 位
int c : 32; // 位段 c,佔 32 位
int : 6; // 無名位段,佔 6 位(填充/對齊)
};
int、unsigned int、signed int;不支援 char、float 等類型。int 為 32 位)。& 運算子取得位址。int 或 unsigned int 參與運算。編譯器會自動優化位段結構的儲存佈局,遵循以下原則(以 MSVC 為例,位段儲存單元 = 4 位元組):
typedef struct { unsigned int a : 1; } S; // 至少 1 位非零位段 → 4 bytes
typedef struct { unsigned int : 0; } S1; // 僅一個 0 寬無名位段 → C: 0 bytes, C++: 1 byte
typedef struct {
unsigned int a : 1;
unsigned int : 0; // 強制換到下一個儲存單元
unsigned int c : 32;
} S2; // 4 + 4 = 8 bytes
typedef struct {
unsigned int a : 4;
unsigned int : 0;
int : 6; // 新儲存單元
unsigned int c : 32; // 6+32>32 → 再換一個儲存單元
} S3; // 4 + 4 + 4 = 12 bytes
typedef struct {
unsigned int a : 1;
char b; // 普通成員也納入位段單元計算
int c : 1;
int d : 2;
unsigned int e : 2;
} S4; // 全部放入一個單元 → 4 bytes
輸出:
1 -1 -2 3
4 1 8 12 4
注意 S4 中 c(1 位有號)賦值 1 後列印為 -1,d(2 位有號)賦值 2(二進位 10)列印為 -2。原因是有號位段數值為負時,參與運算會進行符號擴展(高位補 1),導致整型提升後的值為負數。這提醒我們:對有號位段賦值時務必留意其可表示範圍。
位段是 C 語言進行精細記憶體控制的利器,但其行為受編譯器實作影響較大(如儲存單元大小、位段分配順序、有號位段處理)。實際開發中應:
unsigned int 避免符號擴展陷阱。:0)控制對齊。uint32_t 等)搭配位運算替代,提高可移植性。