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

C 語言位域:精確控制記憶體位元配置

     編輯:C 語言基礎

某些資料在儲存時不需佔用完整位元組,僅需幾個位元即可。例如開關狀態僅需 1 位元。C 語言提供位域機制,允許在結構體中指定成員佔用的位元數。

位域定義語法

struct bs {
    unsigned m;        // 佔 4 位元組
    unsigned n : 4;    // 佔 4 位元
    unsigned char ch : 6; // 佔 6 位元
};

冒號後的數字限定該成員佔用的位元數。未限定者依資料類型決定長度。

位域數值範圍與溢出行為

位域成員的取值範圍受位元數限制。超出範圍時,高位會被直接截斷:

#include <stdio.h>
int main() {
    struct bs {
        unsigned m;
        unsigned n : 4;
        unsigned char ch : 6;
    } a = { 0xad, 0xE, '$' };

    printf("%#x, %#x, %c\n", a.m, a.n, a.ch); // 0xad, 0xe, $

    a.m = 0xb8901c;
    a.n = 0x2d;      // 二進位 10 1101 → 截斷為 1101 (0xd)
    a.ch = 'z';      // ASCII 0x7a → 二進位 111 1010 → 截斷為 11 1010 (0x3a ':')
    printf("%#x, %#x, %c\n", a.m, a.n, a.ch); // 0xb8901c, 0xd, :
    return 0;
}

位域寬度限制與標準規範

  • 位域寬度不能超過其依附資料類型的長度(如 unsigned int 為 32 位,unsigned char 為 8 位)。
  • ANSI C 僅允許 int、signed int、unsigned int;C99 新增 _Bool。但主流編譯器擴展支援 char、enum 等類型。

位域記憶體配置規則

C 標準未強制規定配置細節,編譯器盡量壓縮空間。主要規則如下:

1. 相鄰同類型成員

  • 位寬總和 ≤ 類型大小:緊密排列,無間隙。
  • 位寬總和 > 類型大小:下一成員從新儲存單元開始(偏移量為類型大小的整數倍)。
struct bs {
    unsigned m : 6;
    unsigned n : 12;
    unsigned p : 4;
}; // 總位寬 22 < 32,sizeof = 4 位元組

若將 m 改為 22 位,總和 34 > 32,n 另起爐灶,sizeof = 8。

2. 相鄰不同類型成員

  • GCC:壓縮儲存。
  • VC/VS:不壓縮,各自按類型對齊儲存。

3. 穿插非位域成員

若成員間穿插一般變數,不進行壓縮,各編譯器行為一致。

無名位域:填充與對齊

struct bs {
    int m : 12;
    int : 20;   // 無名位域,用於填充
    int n : 4;
};

無名位域不可存取,常用於調整後續成員位置或強制對齊。上例中若無 20 位填充,sizeof = 4;有填充則 sizeof = 8。

重要限制

位域成員不佔用完整位元組,且可能不在位元組邊界,因此不能取址(&),C 語言明確禁止對位域成員使用取址運算子。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved