4
struct A
{
 int a:2;
 int b:3;
 int c:3;
};

int main()
{
 struct A p = {2,6,1};
 printf("\n%d\n%d\n%d\n",p.a,p.b,p.c);
 return 0;
}    

出力: -2,-2,1

上記のコードを C コンパイラと C++ コンパイラで実行すると、どのような出力が得られるでしょうか? なぜ?

4

4 に答える 4

5

あなたのシステムは2 の補数を使用しているようです。2-bitビットフィールドの保持は、2 の補数システムにあるバイナリに2なります。2の補数表現も同様です。そしてわかりやすい10-2110(6)-23-bit11

ここで符号付きビットフィールドについても読んでください

于 2012-04-25T17:51:13.863 に答える
3

C コンパイラで -2 -2 1 が得られます。問題は、格納しようとしている数値に対してビット フィールドが小さすぎることです。最初の 2 つのケースでは、左端のビットが 1 であるため、負の数として解釈されます。これを修正するには、次のいずれかを行います。

  1. ビットフィールドを大きくする
  2. ビット フィールドを int ではなく unsigned int として宣言する
  3. 印刷する前に unsigned int にキャストし、%u を使用して印刷します。
于 2012-04-25T17:43:10.477 に答える
1

次に、正確に何が起こっているかを見てみましょう。与えられたコードから始めましょう:

struct A
{
 int a:3;
};
int main()
{
 struct A p = {5};
 printf("%d",p.a);
}

この3ビットセットの符号ビットは1であり、したがって負の値であるため、3ビット以内の値は101(5)になります。したがって、011(3)となる101の2の補数を見つける必要があります。したがって、上記のロジックを適用すると、-3として出力されます。同様に他の人も証明できます。

たとえば、1001(9)の場合、a:3のために3ビット値を取ります。したがって、001(1)になります。ここでは符号ビットが設定されていないため、つまり1なので、2の補数を使用する必要はありません。簡単な答えは1です。同様に他のこともできます。

于 2012-04-26T15:18:50.903 に答える
1

このプログラムと同じ理由で、これらの答えが得られます。

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    int32_t a = 4294967294;
    printf("%d\n", a);
    return 0;
}

出力あり-2。大きすぎて収まらない数値で符号付き変数を初期化すると、異なる解釈が行われます。仕様から:

それ以外の場合、新しい型は署名され、値を表現できません。結果が実装定義であるか、実装定義のシグナルが発生します。

于 2012-04-25T17:43:18.273 に答える