C言語のビットドメインとビットセグメントの浅い分析

3514 ワード

C構造体のビットドメイン(ビットセグメント)一部の情報は、格納時に完全なバイトを占有する必要はなく、数または1つのバイナリビットを占有するだけである.例えば、1つのスイッチング量を格納する場合、0と1の2つの状態だけで、1ビットの2進位でよい.記憶領域を節約し、処理を簡便にするために、C言語は「ビットドメイン」または「ビットセグメント」と呼ばれるデータ構造を提供する.「ビットドメイン」とは、1バイトのバイナリビットをいくつかの異なる領域に分割し、各領域のビット数を説明するものである.各ドメインにはドメイン名があり、プログラム内でドメイン名で操作できます.これにより,いくつかの異なるオブジェクトを1バイトのバイナリビットドメインで表すことができる.
一、ビットドメインの定義とビットドメイン変数の説明ビットドメイン定義は構造定義と類似しており、その形式はstructビットドメイン構造名{ビットドメインリスト}である.ここで、ビットドメインリストの形式は次のとおりです.
タイプ説明子ビットドメイン名:ビットドメイン長ビットドメイン変数の説明は、構造変数の説明と同じです.先に定義してから説明し、同時に説明を定義したり、直接説明したりする3つの方法を採用することができます.例:
 
  
struct bs
{
  int a:8;
  int b:2;
  int c:6;
}data;

説明dataはbs変数で、2バイトを占めています.ここで、ビットドメインaは8ビット、ビットドメインbは2ビット、ビットドメインcは6ビットを占める.ビットドメインの定義については、以下の説明があります.
1.1つのビットドメインは同じバイトに格納する必要があり、2バイトにまたがることはできません.1バイトの空き領域が他のビットドメインを格納するのに足りない場合は、次のユニットからビットドメインを格納する必要があります.あるビットドメインを次のユニットから意図的に開始させることもできます.例:
 
  
struct bs
{
    unsigned a:4
    unsigned b:5 /* */
    unsigned c:4
}

2.ビットドメインは2バイトにまたがることが許されないため、ビットドメインの長さは1バイトの長さより大きくすることはできない.
3.ビットドメインは、ビットドメイン名なしで使用できます.この場合、位置の入力または調整にのみ使用されます.無名のビットドメインは使用できません.例:
 
  
struct k
{
    int a:1
    int :2 /* , 2 */
    int b:3
    int c:2
};

二、位域の使用次の例は、ある会社(ホワイトカラー科学技術-青島)の筆記試験に参加して出会ったもので、その時は間違っていたので、忘れないように急いで書いた.
 
  
#include
  #include
  using namespace std;
  struct A
  {
      int a:5;
      int b:3;
  };
  int main(void)
 {
     char str[100] = "0134324324afsadfsdlfjlsdjfl";
         struct A d;
     memcpy(&d, str, sizeof(A));
     cout << d.a << endl;
     cout << d.b << endl;
     return 0;
 }

32ビットx 86マシンに出力:
 
  
?
$ ./langxun.exe
-16
1

解析:デフォルトでは、構造体内の要素へのアクセスと管理を容易にするために、構造体内の要素の長さがプロセッサのビット数より小さい場合、構造体内の最も長い要素をその単位とし、すなわち構造体の長さは必ず最も長いデータ要素の整数倍である.構造体メモリの長さがプロセッサのビット数より大きい要素がある場合は、プロセッサのビット数を位置合わせユニットとします.32ビットプロセッサであり、構造体のaおよびb要素タイプがint(4バイト)であるため、構造体のA占有メモリは4バイトである.
前述のプログラムでは、ビットドメイン構造Aが定義されており、2つのビットドメインはa(5ビット占有)、b(3ビット占有)であるため、aおよびbは、構造Aの合計1バイト(下位の1バイト)を占有する.
プログラムが14行まで実行された場合、dメモリの割り当て状況:
 
  
  00110100 00110011   00110001    00110000
       '4'       '3'       '1'          '0' 
  d.a d.b d (00110000),d.a : 10000, d.b : 001

d.aメモリにおけるバイナリ表現は10000であり、d.aはシンボル付き整数変数であるため、出力時にシンボルビットを拡張するため、結果は-16(バイナリは11111111111111111111111111111111111111111110000)である
d.bメモリのバイナリ表現は001であり、d.bは符号付き整数変数であるため、出力時に符号ビットを拡張しなければならないため、結果は1(バイナリは00000000000000000000000000000000000000000000000000000)である
三、ビットドメインの位置合わせ構造体にビットドメイン(bit-field)が含まれている場合、VCの準則は以下の通りである.
1)隣接するビットフィールドのタイプが同じで、そのビット幅の和がタイプのsizeofサイズより小さい場合、後続のフィールドは前のフィールドに隣接して格納され、収容できないまで格納される.
2)隣接するビットフィールドのタイプが同じで、そのビット幅の和がタイプのsizeofサイズより大きい場合、後続のフィールドは新しいメモリセルから始まり、そのオフセット量はタイプサイズの整数倍になる.
3)隣接するビットドメインフィールドのタイプが異なる場合、各コンパイラの具体的な実装に差があり、VC 6は非圧縮方式(異なるビットドメインフィールドは異なるビットドメインタイプバイトに格納される)を採用し、Dev-C++とGCCはいずれも圧縮方式を採用する.
システムは、まず構造体メンバーにスペースとフィルタを配置し、変数をビットドメイン操作します.