Cprogramming-c-bit-fields

提供:Dev Guides
移動先:案内検索

C-ビットフィールド

あなたのCプログラムには、次のようにステータスと呼ばれる構造にグループ化されたいくつかの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バイトのメモリ空間が必要ですが、値の保存に使用されるのは2ビットのみです。

各変数が1ビットの幅を持つ最大32個の変数を使用する場合、ステータス構造も4バイトを使用します。 ただし、33個の変数があるとすぐに、メモリの次のスロットが割り当てられ、8バイトの使用が開始されます。 私たちは概念を理解するために次の例をチェックしましょう-

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

次の表は、ビットフィールドの変数要素を説明しています-

Sr.No. Element & Description
1

type

ビットフィールドの値の解釈方法を決定する整数型。 タイプは、int、signed int、またはunsigned intです。

2

member_name

ビットフィールドの名前。

3

width

ビットフィールドのビット数。 幅は、指定されたタイプのビット幅以下でなければなりません。

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

struct {
   unsigned int age : 3;
} Age;

上記の構造定義は、年齢変数が値を格納するために3ビットのみを使用することをCコンパイラに指示します。 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 ) : 4
Age.age : 4
Age.age : 7
Age.age : 0