C言語のビットセグメント
ビットフィールドは、構造体 (または共用体) 内のメンバー変数が占めるスペースをビット単位で定義します。ビットセグメントを含む構造(和集合)をビットセグメント構造と呼びます。分割構造により省スペースかつ操作性が向上します。
ビットフィールドの定義形式は次のとおりです:
type [var]:digits
type は int、unsigned int、signed のみです int には 3 つの型があります (int 型が負の数を表現できるかどうかはコンパイラによって異なります。たとえば、VC の int はデフォルトで signed になります) int は負の数を表すことができます)。ビット フィールド名 var はオプションのパラメータであり、省略できます。桁数は、このビット フィールドが占める 2 進数の桁数を表します。
次に、ビット セグメント構造の定義は、次のコードのように定義できます:
struct node { unsigned int a:4; //位段a,占4位 unsigned int :0; //无名位段,占0位 unsigned int b:4; //位段b,占4位 int c:32; //位段c,占32位 int :6; //无名位段,占6位 };
1. ビット セグメントの使用
ビット セグメントを使用する際に注意すべき点がいくつかあります:
1) ビット セグメントのタイプは、 unsigned int と signed int の 3 つのタイプがあり、char 型または浮動小数点型にすることはできません
2) ビットフィールドが占める 2 進数の桁数は、次の式で表現できる最大桁数を超えることはできません。たとえば、VC の int が 4 バイトを占める場合、最大でも 32 ビットしか使用できません
3) 名前のないビット フィールドにはアクセスできませんが、スペースを占有します。ビットフィールド用に取得されます
5) ビット フィールドが占める 2 進数の数が 0 の場合、このビット フィールドは名前のないビット フィールドでなければならず、次のビット フィールドは次のビット フィールド ストレージ ユニット (ここでのビット フィールド ストレージ ユニットの数) に格納されます。 VC 環境では 4 であることがテストされています) Byte) の保存が開始されます
6) 式にビット フィールドが出現すると、自動的に整数型にアップグレードされ、int 型または unsigned int に変換されます。
7) ビット セグメントに値を割り当てるときは、ビット セグメントが表現できる最大範囲を超えないことが最善です。そうしないと、予期しない結果が発生する可能性があります。
8) ビットフィールドを配列の形式にすることはできません。
2. ビット セグメント構造がメモリに格納される方法
ビット セグメント構造に関して、主な原則は次のとおりです。 1) ビット セグメント ストレージ ユニットが下位ビット セグメント構造内のすべてのメンバーを格納できる場合、ビット セグメント構造内のすべてのメンバーは 1 つのビット セグメント ストレージ ユニットにのみ配置でき、2 つのビット セグメント ストレージ ユニットに配置することはできません。 1 つのビット セグメント記憶ユニットが下位ビット セグメント構造内のすべてのメンバーを収容できない場合、残りのビット セグメントは次のビット セグメント記憶ユニットから記憶されます。 (VCのセグメント記憶ユニットのサイズは4バイトです)。
2) ビット セグメント構造内に 0 ビットを占有する名前のないビット セグメントが 1 つだけある場合、それは 1 バイトまたは 0 バイトのスペースのみを占有します (C 言語では 0 バイト、C++ では 1 バイト)。それ以外の場合は、次のようになります。ビットセグメント構造が占めるスペースは少なくともビットセグメントストレージユニットのサイズです。
テストプログラム:
/*测试位段 201110.12*/ #include<iostream> using namespace std; typedef struct node { unsigned int a:1; //存在一个非0位的位段,则至少占4Byte }S; typedef struct node1 //在C++中占1字节的空间 ,在C中占0字节 { unsigned int :0; }S1; typedef struct node2 { unsigned int a:1; unsigned int :0; //下一个位段放在一个新的位段存储单元 ,所以占4+4=8Byte unsigned c:32; }S2; typedef struct node3 { unsigned int a:4; unsigned int :0; int :6; //这个位段放在一个新的位段存储单元 unsigned c:32;//由于6+32>32,所位段c也放在一个新的位段存储单元,所以占4+4+4=12Byte }S3; typedef struct node4 { unsigned int a:1; char b; //在一个位段存储单元中能够存下所有的成员,所以占4Byte int c:1; int d:2; unsigned int e:2; }S4; nt main(int argc, char *argv[]) { S4 s4; s4.a=1; s4.c=1; s4.d=2; s4.e=3; printf("%d %d %d %d\n",s4.a,s4.c,s4.d,s4.e); printf("%d %d %d %d %d\n",sizeof(S),sizeof(S1),sizeof(S2),sizeof(S3),sizeof(S4)); return 0; }
実行結果:
1 -1 -2 3
4 1 8 12 4を押してください。
s4 の各ビットフィールドを出力すると、割り当てられた初期値とは異なります。
c は 1 ビットしか占有しないので、このとき、上位ビットに直接 1 を加算する符号拡張が実行されるため、出力結果は -1 になります。
d は 2 ビットを占有するため、次のようになります。 dに2が代入され、メモリに格納されている内容は10です。このとき符号拡張が行われ、上位ビットに1を補うと0XFF FF FF FEとなり、その真の値は-2になります
読んでいただきありがとうございます。皆さんのお役に立てれば幸いです。このサイトのサポートにご興味をお持ちいただきありがとうございます。