C言語でif文でtrue/false判定をすることを考えてみましょう。
以下のようなtrue/false判定をするための構造体を用意してみます。
1 2 3 4 5 6 |
struct { unsigned int isValidated; unsigned int isUsed; } myBool; |
この構造体はisValudated(有効かどうか)、isUsed(使われているかどうか)という情報を保存するためのものです。
この2つの情報を保持するためには、0か1かしか無いので必要なメモリ領域は2バイトだということが分かります。
ここで以下のようにこの構造体のサイズを出力してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <stdio.h> struct { unsigned int isValidated; unsigned int isUsed; } myBool; int main(void) { printf("Size: %lu\n", sizeof(myBool)); return 0; } |
出力は、
1 2 3 |
Size: 8 |
となります。
つまり本来必要なバイト数は2バイトにもかからわず、構造体のメモリ領域が8バイトになってしまっているわけです。
この場合は無駄が6バイト分なので大した問題にはならないのですが、
true/false用のメンバが沢山ある場合や構造体が何個も存在している場合には、無視できない規模のメモリの無駄遣いになってしまいます。
こんなときにメモリ領域を活用するために役に立つ機能が、『ビットフィールド』です。
ビットフィールドは構造体に備わっている機能で、
『型 名前: サイズ;』
というふうに使います。
サイズはビット数のことです。5とすれば、その変数には5ビットのメモリ領域が割り当てられることになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include <stdio.h> struct { unsigned int isValidated: 1; unsigned int isValidated2: 1; } myBool; int main(void) { printf("Size: %lu\n", sizeof(myBool)); return 0; } |
このコードは、構造体のメンバにビットフィールドを適用した例です。
構造体変数のメモリ領域は
1 2 3 |
Size: 4 |
となっていますが、メンバ変数に使われている実際のメモリ領域は2ビットとなっています。
以下のコードも実行してみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#include <stdio.h> struct { unsigned int isValidated: 1; unsigned int isValidated2: 1; unsigned int isValidated3: 1; unsigned int isValidated4: 1; unsigned int isValidated5: 1; unsigned int isValidated6: 1; unsigned int isValidated7: 1; unsigned int isValidated8: 1; unsigned int isValidated9: 1; unsigned int isValidated10: 1; unsigned int isValidated11: 1; unsigned int isValidated12: 1; unsigned int isValidated13: 1; unsigned int isValidated14: 1; unsigned int isValidated15: 1; unsigned int isValidated16: 1; unsigned int isValidated17: 1; unsigned int isValidated18: 1; unsigned int isValidated19: 1; unsigned int isValidated20: 1; unsigned int isValidated21: 1; unsigned int isValidated22: 1; unsigned int isValidated23: 1; unsigned int isValidated24: 1; unsigned int isValidated25: 1; unsigned int isValidated26: 1; unsigned int isValidated27: 1; unsigned int isValidated28: 1; unsigned int isValidated29: 1; unsigned int isValidated30: 1; unsigned int isValidated31: 1; unsigned int isValidated32: 1; } myBool; int main(void) { printf("Size: %lu\n", sizeof(myBool)); return 0; } |
やはり、構造体のメモリ領域は4バイトとなっています。
構造体のメンバは1ビットが32個分で32ビット(=4バイト)になります。
ちなみにあと1ビットのメンバをあと1つ増やすと、構造体のメモリ領域は8バイトになります。(確かめてみましょう!)