3
#include <stdio.h>

int main(int argc, char const *argv[])
{
  char  a = 0xAA;
  int b;

  b = (int)a;
  b = b >> 4;

  printf("%x\n", b);
  return 0;
}

ここで出力はfffffffaです。この出力がどのように得られたかを誰かに説明してもらえますか?

4

3 に答える 3

3

C 標準では、コンパイラの設計者charは が符号付きか符号なしかを選択できます。お使いのシステムでは、署名付きcharの と 32 ビットintの が使用されているようです。0xAA(binary )の最上位ビット10101010が設定されているため、値は に符号拡張され0xFFFFFFAAます。

符号付きの値を右にシフトすると、結果も符号拡張されるため、下位 4 ビットをシフト アウトすると、左から 4 つの 1 がシフト インされ、 の最終出力が得られます0xFFFFFFFA

編集: C99 仕様によると、例のような 16 進整数定数は、長さに応じて異なる長さの s0xAAとして扱われます。intしたがって、0xAAsigned への代入charは範囲外です。値を代入する適切な方法は、次のように 16 進文字リテラルを使用することです。

char a='\xAA';
于 2013-07-15T17:19:41.370 に答える
2

0xFFFFFFAA に int に入れると、0xAA が符号拡張されたように見えます。次に、それを 4 ビット (1 16 進文字) だけ右シフトすると、最終的に 0xFFFFFFFA になります。

  //a is 8-bits wide.  If you interpret this as a signed value, it's negative
  char a=0xAA;

  int b; //b is 32 bits wide here, also signed

  //the compiler sign-extends A to 0xFFFFFFAA to keep the value negative
  b=(int)a; 

  b=b>>4; //right-shift maintains the sign-bit, so now you have 0xFFFFFFFA
于 2013-07-15T17:19:35.690 に答える
2

標準ではcharsignedまたはunsignedあなたの場合は のように見えますsigned0xAAへの代入signed char符号付きオーバーフローであるため、動作は未定義です。したがって、宣言を次のように変更すると、次のようになります。

unsigned char a=0xAA;

期待する結果が得られるはずです。

于 2013-07-15T17:20:33.537 に答える