0
#include<stdio.h>
int main()
{
unsigned short a=-1;
printf("%d",a);
return 0;
}
  1. これにより、出力 65535 が得られます。なぜですか?
  2. a の値を負側に増やすと、出力は (2^16-1=)65535-a になります。
  3. unsigned short int の範囲が 0 から 65535 であることは知っていますが、なぜ 0 から 65535 の範囲で回転しているのでしょうか。

    #include<stdio.h>
    int main()
    {
    unsigned int a=-1;
    printf("%d",a);
    return 0;
    }
    
  4. 出力は -1 です。
  5. %d は、ここでその (int) 範囲の最大値を出力する規則に従っていない理由よりも、符号付き 10 進整数に使用されます。
  6. この部分の出力が -1 なのはなぜですか?
  7. %u が符号なし 10 進整数の出力に使用されることは知っています。

    最初のコードではなく、2 番目のコードでビヘイビアが定義されていないのはなぜですか?

    これは、gcc コンパイラでコンパイルしたものです。これは C コードです。私のマシンでは、short int のサイズは 2 バイトで、int のサイズは 4 バイトです。

4

2 に答える 2

3

あなたの実装では、short は 16 ビットで、int は 32 ビットです。

unsigned short a=-1;
printf("%d",a);

まず、-1 を に変換しunsigned shortます。この結果、値は 65535 になります。正確な定義については、標準の「整数変換」を参照してください。要約すると、値は modulo で取得されUSHORT_MAX+1ます。

この値 65535 が に割り当てられaます。

次に、printfvarargs を使用する の場合、値は に昇格されintます。varargs は int より小さい整数型を渡すことはなく、常に int に変換されます。これにより、値 65535 が出力されます。

unsigned int a=-1;
printf("%d",a);

最初の行は前と同じですが moduloUINT_MAX+1です。a4294967295 です。

printf の場合、aとして渡されますunsigned int%dが必要であるため、int動作は C 標準では定義されていません。しかし、実装では、すべてのビットが設定された符号なしの値 4294967295 が、すべてのビットが設定された符号付き整数、つまり 2 の補数の値 -1 として再解釈されたようです。この動作は一般的ですが、保証されていません。

于 2012-10-22T09:30:30.827 に答える
0

変数の割り当ては、変数の型のメモリ量に対して行われます (たとえば、32 ビット ハードウェアでは通常、short は 2 バイト、int は 4 バイトです)。代入では、変数の符号は重要ではありません。ここで重要なのは、どのようにアクセスするかです。「short」(符号付き/符号なし) に割り当てると、値が「2 バイト」メモリに割り当てられます。printf で '%d' を使用する場合、printf はそれを '整数' (ハードウェアでは 4 バイト) と見なし、2 つの MSB は 0 になるため、[0|0](2 つの MSB) [- 1] (2 つの LSB)。新しい MSB (printf、移行で %d によって導入された) により、符号ビットは LSB に隠されているため、printf は符号なしと見なし (MSB が 0 であるため)、正の値が表示されます。これを否定するには、最初のケースで '%hd' を使用する必要があります。2 番目のケースでは、'4 バイト' メモリに割り当て、MSB は割り当て中に SIGN ビット '1' (負を意味する) を取得したため、printf の '%d' に負の数が表示されます。それが説明することを願っています。より明確にするために、答えにコメントしてください。

注意: 上位バイトの省略形として「MSB」を使用しました。文脈に応じて読んでください(たとえば、「SIGNビット」は「Most Significant Bit」のように読みます)。ありがとう。

于 2012-10-22T09:30:12.833 に答える