C語言中的位域



當我們宣告一個結構體或聯合體型別時,結構體/聯合體型別變數的大小取決於其各個元素的大小。您可以設定位的大小來限制大小,而不是使用預設的記憶體大小。指定的大小稱為位域

這是宣告位域的語法

struct {
   data_type elem : width;
};

假設您的 C 程式包含許多在名為status的結構體中分組的 TRUE/FALSE 變數,如下所示:

struct {
   unsigned int widthValidated;
   unsigned int heightValidated;
} status;

此結構體需要 8 位元組的記憶體空間,但實際上,我們每個變數都只儲存“0”或“1”。C 語言提供了一種更好的方法來利用此類情況下的記憶體空間。

如果您在結構體中使用此類變數,則可以定義變數的寬度,這告訴 C 編譯器您只打算使用那麼多位元組。例如,上述結構體可以改寫如下:

struct {
   unsigned int widthValidated : 1;
   unsigned int heightValidated : 1;
} status;

上述結構體需要 4 位元組的記憶體空間來儲存status變數,但只使用 2 位來儲存值。

示例

如果您最多使用 32 個變數,每個變數的寬度為 1 位,那麼status結構體也將使用 4 個位元組。但是,一旦您有 33 個變數,它將分配下一個記憶體槽,並將開始使用 8 個位元組。

讓我們檢查以下示例以瞭解這個概念:

#include <stdio.h>

/* define simple structure */
struct {
   unsigned int widthValidated;
   unsigned int heightValidated;
} status1;

/* define a structure with bit fields */
struct {
   unsigned int widthValidated : 1;
   unsigned int heightValidated : 1;
} status2;

int main() {

   printf("Memory size occupied by status1: %d\n", sizeof(status1));
   printf("Memory size occupied by status2: %d\n", sizeof(status2));
   
   return 0;
}

輸出

編譯並執行上述程式碼後,將產生以下輸出:

Memory size occupied by status1: 8
Memory size occupied by status2: 4

位域宣告

位域的宣告在結構體內部具有以下形式:

struct {
   type [member_name] : width ;
};

下表描述了位域的變數元素:

元素 描述
型別

一個整數型別,它決定如何解釋位域的值。

型別可以是int、signed intunsigned int

成員名稱 位域的名稱。
寬度 位域中的位數。“寬度”必須小於或等於指定型別的位寬。

使用預定義寬度定義的變數稱為位域。位域可以容納多個位;例如,如果您需要一個變數來儲存 0 到 7 的值,則可以定義一個寬度為 3 位的位域,如下所示:

struct {
   unsigned int age : 3;
} Age;

上述結構體定義指示 C 編譯器變數“Age”將僅使用 3 位來儲存值。如果您嘗試使用超過 3 位,則它將不允許您這樣做。

示例

讓我們嘗試以下示例:

#include <stdio.h>

struct {
   unsigned int age : 3;
} Age;

int main() {

   Age.age = 4;
   printf("Sizeof(Age): %d\n", sizeof(Age));
   printf("Age.age: %d\n", Age.age);

   Age.age = 7;
   printf("Age.age : %d\n", Age.age);

   Age.age = 8;
   printf("Age.age : %d\n", Age.age);

   return 0;
}

輸出

編譯上述程式碼時,將出現警告:

warning: unsigned conversion from 'int' to 'unsigned char:3' changes value from '8' to '0' [-Woverflow]|

執行時,將產生以下輸出:

Sizeof(Age): 4
Age.age: 4
Age.age: 7
Age.age: 0

您可以在儲存空間有限的情況下使用位域。當裝置傳輸編碼到多個位中的狀態或資訊時,位域也很有效。每當某些加密程式需要訪問位元組內的位時,都使用位域來定義資料結構。

廣告