次の方法で共有


C ビット フィールド

構造体または共用体のメンバーの宣言子に加えて、構造体宣言子は、"ビット フィールド" と呼ばれる指定されたビット数にすることもできます。その長さは、コロンによってフィールド名の宣言子から設定されます。 ビット フィールドは整数型として解釈されます。

構文

struct-declarator=
declarator
type-specifier declaratoropt : constant-expression

constant-expression は、フィールドの幅 (ビット単位) を指定します。 declaratortype-specifier は、unsigned intsigned int、または int である必要があります。constant-expression は負でない整数値である必要があります。 値がゼロの場合、宣言には declarator がありません。 ビット フィールド、ビット フィールドへのポインター、およびビット フィールドを返す関数の配列は使用できません。 省略可能な declarator はビット フィールドの名前を指定します。 ビット フィールドは構造体の一部としてしか宣言できません。 アドレス演算子 (&) は、ビット フィールド コンポーネントに適用できません。

名前のないビット フィールドは参照できず、実行時の内容は予測できません。 これらはアラインメントのために "ダミー" フィールドとして使用できます。 幅が 0 として指定された、名前のないビット フィールドは、struct-declaration-list 内でそれに続くメンバーのストレージが、int 境界で開始されることを保証します。

ビット フィールドのビット数は、基になる型のサイズ以下である必要があります。 たとえば、次の 2 つのステートメントは正しくありません。

short a:17;        /* Illegal! */
int long y:33;     /* Illegal! */

次の例では、screen という名前の構造体の 2 次元配列を定義します。

struct
{
    unsigned short icon : 8;
    unsigned short color : 4;
    unsigned short underline : 1;
    unsigned short blink : 1;
} screen[25][80];

配列には 2,000 の要素が含まれます。 各要素は、iconcolorunderline、および blink の 4 つのビット フィールド メンバーを含む個別の構造体です。 各構造体のサイズは 2 バイトです。

ビット フィールドには、整数型と同じセマンティクスがあります。 同じ基本型の変数が使用される場合とまったく同じように、式でビット フィールドが使用されます。 ビット フィールドにあるビット数は関係ありません。

Microsoft 固有の仕様

int として定義されたビット フィールドは、 signed として扱われます。 ANSI C 標準への Microsoft 拡張機能を使用すると、ビット フィールドに対して char 型と long 型 ( signedunsigned 両方) が許可されます。 基本型が longshort、または char (signed または unsigned) である名前のないビット フィールドは、基本型に適した境界に強制的に配置されます。

ビット フィールドは、整数内で最下位ビットから最上位ビットへと割り当てられます。 次のコードでは、

struct mybitfields
{
    unsigned short a : 4;
    unsigned short b : 5;
    unsigned short c : 7;
} test;

int main( void )
{
    test.a = 2;
    test.b = 31;
    test.c = 0;
    return 0;
}

test のビットは次のように配置されます。

00000001 11110010
cccccccb bbbbaaaa

8086 ファミリのプロセッサでは、整数値の下位バイトを上位バイトの前に格納するため、0x01F2 という整数は、0xF2 の後に 0x01 が続く形で物理メモリに格納されます。

ISO C99 標準では、ビット フィールドが 2 つのストレージ インスタンスをまたげるかどうかを実装で選択できます。 たとえば、合計で 64 ビットになるビット フィールドが格納される、次の構造体を考えてみます。

struct
{
    unsigned int first : 9;
    unsigned int second : 7;
    unsigned int may_straddle : 30;
    unsigned int last : 18;
} tricky_bits;

標準 C 実装では、これらのビット フィールドを 2 つの 32 ビット整数にパックできます。 tricky_bits.may_straddle は、1 つの 32 ビット整数では 16 ビットとして、次の 32 ビット整数では 14 ビットとして格納される場合があります。 Windows ABI 規則では、ビット フィールドを 1 つのストレージ整数にパックし、ストレージ ユニットにはまたがりません。 上記の例では、Microsoft コンパイラに各ビット フィールドが格納されるため、1 つの 32 ビット整数に完全に収まります。 この場合、firstsecond は 1 つの整数に格納され、may_straddle は 2 番目の整数に格納され、last は 3 番目の整数に格納されます。 sizeof 演算子は、tricky_bits のインスタンスに対して 12 を返します。 詳細については、「構造体メンバーの埋め込みと配置」を参照してください。

Microsoft 固有の仕様はここまで

関連項目

構造体宣言