Cビットフィールド


プログラムの構造に複数のスイッチが含まれる場合、次のように TRUE/FALSE 変数のみが存在します:

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

この構造には 8 バイトのメモリ空間が必要ですが、実際には、各変数には 0 または 1 のみが格納されます。この場合、C 言語はメモリ空間をより有効に活用する方法を提供します。このような変数を構造体内で使用する場合は、変数の幅を定義して、これらのバイトのみを使用することをコンパイラーに伝えることができます。たとえば、上記の構造は次のように書き換えることができます:

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

さて、上記の構造では、ステータス変数は 4 バイトのメモリ空間を占有しますが、値を格納するために使用されるのは 2 ビットだけです。 32 個の変数を使用する場合、各変数は 1 ビット幅であり、ステータス構造体は 4 バイトを使用しますが、さらに 1 つの変数を使用するとすぐに、33 個の変数を使用すると、メモリの次のセクションが割り当てられます。 33 番目の変数、この時点では 8 バイトが使用されます。この概念を理解するために次の例を見てみましょう:

#include <stdio.h>#include <string.h>/* 定义简单的结构 */struct{  unsigned int widthValidated;  unsigned int heightValidated;} status1;/* 定义位域结构 */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 : 8Memory size occupied by status2 : 4

ビットフィールド宣言

構造体内でのビットフィールドの宣言は次のようになります:

struct{
  type [member_name] : width ;};

以下は、ビット フィールドの変数要素の説明です。

要素 説明
type 整数型は、ビット フィールドの値がどのように解釈されるかを決定します。型には、整数、符号付き整数、または符号なし整数を指定できます。
member_name ビットフィールドの名前。
width ビットフィールドのビット数。幅は、指定された型のビット幅以下である必要があります。

幅が事前定義された変数はビットフィールドと呼ばれます。たとえば、0 から 7 までの値を格納する変数が必要な場合は、次のように 3 ビット幅のビットフィールドを定義できます。

struct{  unsigned int age : 3;} Age;

上記の構造定義は、 C コンパイラでは、age 変数はこの値を格納するために 3 ビットのみを使用します。3 ビットを超えて使用しようとしても、実行されません。次の例を見てみましょう:

#include <stdio.h>#include <string.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;}

上記のコードがコンパイルされると、警告が表示され、上記のコードが実行されると、次の結果が生成されます:

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