首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言問答

C 語言位元欄位(Bit-field)詳解:int a : 3 vs 普通 int 的本質差異

     編輯:C 語言問答

什麼是位元欄位?

在 struct 或 union 中,成員後加 : 寬度 即宣告位元欄位:

struct Flags {
    unsigned int flag1 : 1;  // 1 bit
    unsigned int flag2 : 3;  // 3 bits
    unsigned int flag3 : 4;  // 4 bits
};

與普通 int 的核心差異

特性普通 int位元欄位 int a : n
佔用空間固定 sizeof(int)(通常 4 位元組)僅佔 n bits,編譯器盡量壓縮相鄰欄位至同一儲存單元
可取址可用 &a 取得位址不可取址(&a 編譯錯誤),因可能跨位元組邊界
陣列化可宣告陣列 int arr[10]不可宣告陣列
型別限制任意型別僅限 int, unsigned int, signed int, _Bool (C99) 或實作定義型別
存取速度直接載入/儲存字長需額外位元遮罩/位移指令,**稍慢**
攜帶性高位元配置順序(高位在前/低位在前)、跨儲存單元行為由**實作定義**

典型應用場景

  • 硬體暫存器映射(如 GPIO 控制、中斷標誌)
  • 網路協議標頭解析(IP/TCP 標頭欄位位元級切割)
  • 極度受限記憶體環境的旗標集合(如嵌入式狀態機)

程式碼範例:狀態旗標壓縮

#include <stdio.h>

struct DeviceStatus {
    unsigned int power_on   : 1;
    unsigned int error      : 1;
    unsigned int mode       : 3;  // 0-7
    unsigned int reserved   : 29; // 填滿 32 bits
};

int main() {
    struct DeviceStatus s = {0};
    s.power_on = 1;
    s.mode = 5;
    printf("Size: %zu bytes\n", sizeof(s)); // 輸出 4
    // s = *(struct DeviceStatus*)&hardware_register; // 硬體映射
    return 0;
}

避坑指南

  1. **跨平台共享資料結構勿用位元欄位**(序列化請手動位元操作)。
  2. **簽名位元欄位**(int f : 1)正負號表示實作定義,旗標請用 unsigned。
  3. **零寬度欄位**(unsigned int : 0)強制對齊到下一個儲存單元,可用於對齊控制。
  4. 除非有明確壓縮需求,**優先用普通整數 + 位元遮罩**(val & (1<<n)),可讀性、攜帶性、除錯友善度全勝。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved