3

重複の可能性:
この C++ コードの意味は何ですか?

次の C++ コードでは

# include <stdio.h>
int main()
{
  struct clap
  {
   int i:2;
   int j:2;
   int k:3;
   }x={1,2,3};

  printf("%d %d %d",x.i,x.j,x.k);

  return 0;
}

次のコードを実行すると、出力 1 -2 3 が得られます

上記のコードを参照して、「:」演算子の意味と、この奇妙な出力の理由を説明してください。

4

4 に答える 4

8

これらは、コロンの後に長さが示されているビットフィールドを示します

  struct clap
  {
   int i:2; // length 2
   int j:2; // length 2
   int k:3; // length 3
   };

ビットフィールドはスペースを節約します。計算sizeof(clap)してみると、gcc 4.7 では 4 バイトであることがわかります。1 バイトではない理由 (2 + 2 + 3 = 7 ビット < 1 バイト) は、コンパイラが、ビットフィールドの基になる型に応じて、特定の境界に構造体を配置するためです。たとえば、ビットフィールドの基になる型にまたはとして変更intすると、合計サイズがそれぞれ 2 バイトと 1 バイトに減少します (gcc 4.7 で再び)。shortcharclap

これは、3 つの完全な整数を格納するのに通常 12 バイトかかることと比較する必要があります (int が 4 バイトの場合)。OTOH、メンバーのアドレス指定にはビットフィールドのシフトとアンパックが必要なため、ビットフィールドを使用するとコードが遅くなる可能性があります。

符号の問題は、2 ビットの 2 の補数が -2 に等しいために発生します。コードを に拡張すると、int j:3が出力されます2

于 2013-01-15T12:25:39.070 に答える
5

構造体のコロンは、メンバーがビット フィールドであることを意味します。つまり、各フィールドは指定された数のビットのみを使用します。

-2フィールドに対して得られるのjは、おそらくprintf扱いが符号拡張された整数であるためです。

于 2013-01-15T12:25:29.860 に答える
2

それがビットフィールドと呼ばれるものです。

アップデート:

:とx.j出力された理由は 2 ですが、2 ビットしかなく、上位ビットが 1 であるため、with形式で符号ビットと見なされます。それを確認するには、変更して何が起こるかを確認してください。-2x.jprintf%d%d%u

于 2013-01-15T12:26:13.633 に答える
1

他の回答のように、それはビットフィールドです。それらに関する重要な注意事項:

したがって、C++0x は、ビットフィールドの連続したシーケンス内のすべての (長さがゼロでない) ビットフィールドを単一のメモリ位置の一部として扱います。1 つへの割り当ては、他のいずれかへの割り当てと競合します。このような連続したビットフィールドは、異なるスレッドによって同時に更新されるべきではありません。通常、これは単一のロックで保護する必要があることを意味します。

http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/threadsintro.html#bitfields

于 2013-01-15T12:49:54.997 に答える