我尝试过:
int a;
unsigned int *i=(unsigned int*)&a;
*i=~0;
printf("%d\n",a);
我期望答案是肯定的,因为i
是无符号的,但是编译器给出的结果是 -1 。您能否解释一下并指导我在哪里阅读有关这些内容的更多信息?
答案 0 :(得分:1)
正在发生的事情的更具描述性的版本:
您声明了一个变量a
,该变量将包含一个32位值。编译器知道将a
视为有符号整数,但是在运行时,计算机唯一知道的是它存储32位。
(a) -> 00000000
接下来,您设置一个无符号整数i
指向该值。
(*i) --+---> 00000000
(a) --+
所以a和i都引用相同的32位值,但是,根据它们的类型,可以不同地解释该值...
然后将*i
设置为~0
(*i) --+---> FFFFFFFF
(a) --+
然后您打印%d
中的a
。因此,首先a
已签名,但这在这里并不重要。重要的是您将0xFFFFFFFF
作为参数传递给printf("%d"...)
。执行printf时,libc库看到%d
-告诉编译器期望一个代表32位有符号整数(*)的值,因此编译器将使用一个有符号整数到ascii转换器将其转换为人类可读的文本。因为高位是1,所以此解释器将其显示为负数。
我假设您使用的系统使用32位int。某些系统使用16位int,但是如果您使用16位,则使用相同的主体
(*)-根据要编译的系统,%d
可以表示32位或16位整数...您不应该假设%d
指的是32位仅...