#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
。有人可以向我解释一下这个输出是如何获得的吗?
答案 0 :(得分:3)
C标准允许编译器设计者选择char
是签名还是未签名。您的系统似乎使用签名的char
和32位int
。由于设置了0xAA
(二进制10101010
)的最重要位,因此该值会被符号扩展为0xFFFFFFAA
。
右移符号值也会对结果进行符号扩展,因此当您移出低4位时,有4个从左侧移入,导致最终输出为0xFFFFFFFA
。
编辑:根据C99规范,示例中的十六进制整数常量(例如0xAA
)将被视为不同长度的int
,具体取决于其长度。因此,将0xAA
分配给签名的char
超出范围:分配值的正确方法是使用十六进制字符文字,如下所示:
char a='\xAA';
答案 1 :(得分:2)
当你把它放到一个int到0xFFFFFFAA时,看起来像0xAA得到符号扩展。然后,当你将它右移四位(一个十六进制字符)时,你最终得到了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
答案 2 :(得分:2)
标准允许char
为signed
或unsigned
,因为它看起来像是signed
。将0xAA
分配给signed char
是signed overflow因此未定义的行为。因此,如果您将声明更改为:
unsigned char a=0xAA;
你应该得到你期望的结果。