C中的十六进制
我很困惑。为什么在这个程序中a给我0xffffa0而b给我0xA0?真奇怪C中的十六进制,c,hex,C,Hex,我很困惑。为什么在这个程序中a给我0xffffa0而b给我0xA0?真奇怪 #include <stdio.h> int main() { char a = 0xA0; int b = 0xA0; printf("a = %x\n", a); printf("b = %x\n", b); } #包括 int main() { 字符a=0xA0; int b=0xA0; printf(“a=%x\n”,a); printf(“b=%x\n”,b);
#include <stdio.h>
int main()
{
char a = 0xA0;
int b = 0xA0;
printf("a = %x\n", a);
printf("b = %x\n", b);
}
#包括
int main()
{
字符a=0xA0;
int b=0xA0;
printf(“a=%x\n”,a);
printf(“b=%x\n”,b);
}
默认类型的a
为字符a=0xA0中的签名
和在任何有符号数据类型
中,无论其字符是否为int
,都应注意符号位
,如果符号位
为设置
则表示数字为负数,并以两位互补
的方式存储
char a = 0xA0; /* only 1 byte for a but since sign bit is set,
it gets copied into remaining bytes also */
a => 1010 0000
|
this sign bit gets copied
1111 1111 1111 1111 1111 1111 1010 0000
f f f f f f A 0
如果int b=0xA0
符号位(第31位)
为0
,因此将打印其中包含的内容,即0xA0
让我们一步一步来
0xA0
在值为160的整数常量中,键入int
在OP的例子中,char
被编码为具有8位范围的signed char
。160大于最大8位char
,因此将超出范围的值分配给某个有符号整数类型是实现定义的行为。在OP的例子中,值“环绕”和a
的值为160-256或-96
// Try
printf("a = %d\n", a);
使用printf()
(a),char a
将其传递到…
部分,从而通过通常的整数升级到int
,并保留相同的值
printf("a = %x\n", a);
// is just like
printf("a = %x\n", -96);
对于printf()
,%x“
期望值在非负范围内的无符号
或int
。对于int
和-96,两者都不是,因此输出是未定义的行为
典型的未定义行为是将传递的位模式解释为无符号的。int
-96的位模式作为32位int
是0xFFFF0
故事的寓意:
启用编译警告。一个好的编译器会对chara=0xA0代码>和printf(“a=%x\n”,a)代码>
不要依赖未定义的行为
因为char
是signed
,所以0xA0
是负数。没有混淆的理由。由于您没有指定,编译器正在对int
和char
使用其默认签名。printf
格式说明符%x
不知道它被传递了int
(第二种情况)或升级为int
(第一种情况)的char
,它会处理它所提供的数据,在预期无符号int
的上下文中,“默认情况下,a
的类型是有符号的”-->不,它不是。它类似于OP的带符号字符,但这不是默认值。
printf("a = %x\n", a);
// is just like
printf("a = %x\n", -96);
printf("a = %x\n", a);