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是有符号还是无符号。看来您的系统使用 signed chars 和 32-bit ints。0xAA由于设置了(binary )的最高有效位10101010,因此该值被符号扩展为0xFFFFFFAA.

将有符号值右移也会对结果进行符号扩展,因此当您移出低四位时,四个 1 从左移入,最终输出为0xFFFFFFFA.

编辑:根据 C99 规范,您的示例中的十六进制整数常量根据其长度0xAA被视为不同长度的 s。int因此,分配0xAA给有符号char超出范围:分配值的正确方法是使用十六进制字符文字,如下所示:

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

该标准允许char是,signed或者unsigned在您的情况下,它看起来像signed。分配0xAA给 asigned char是有符号溢出,因此是未定义的行为。因此,如果您将声明更改为:

unsigned char a=0xAA;

你应该得到你期望的结果。

于 2013-07-15T17:20:33.537 回答
2

当您将 0xAA 放入到 0xFFFFFFAA 的 int 中时,它看起来像扩展了符号。然后,当您将其右移四位(一个十六进制字符)时,您最终得到 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 回答