#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
。谁能向我解释一下这个输出是如何获得的?
#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
。谁能向我解释一下这个输出是如何获得的?
C 标准允许编译器设计者选择char
是有符号还是无符号。看来您的系统使用 signed char
s 和 32-bit int
s。0xAA
由于设置了(binary )的最高有效位10101010
,因此该值被符号扩展为0xFFFFFFAA
.
将有符号值右移也会对结果进行符号扩展,因此当您移出低四位时,四个 1 从左移入,最终输出为0xFFFFFFFA
.
编辑:根据 C99 规范,您的示例中的十六进制整数常量根据其长度0xAA
被视为不同长度的 s。int
因此,分配0xAA
给有符号char
超出范围:分配值的正确方法是使用十六进制字符文字,如下所示:
char a='\xAA';
该标准允许char
是,signed
或者unsigned
在您的情况下,它看起来像signed
。分配0xAA
给 asigned char
是有符号溢出,因此是未定义的行为。因此,如果您将声明更改为:
unsigned char a=0xAA;
你应该得到你期望的结果。
当您将 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