#include <stdio.h>
#include <stdlib.h>
typedef unsigned int U32;
int main() {
U32 var = -1;
printf("var = %u\n", var);
if(var != -1)
{
printf("\n I'm not -1\n");
}
else
{
printf("I'm -1 and Var :%u\n", var);
}
}
此处“ -1”应转换为unsigned
int
,并应分配给var
。然后在if
条件下,它不应等于-1。但这要进入else
语句。
答案 0 :(得分:3)
请注意,所有整数常量,例如1
都有一个类型。假设U32
为unsigned int
,则:
对于U32 var = -1;
(分配),类型为int
的右操作数将转换为左操作数的类型。
在if(var != -1)
的情况下,按照通常的算术转换-1操作数从类型int
转换为unsigned int
>,详细信息在这里:Implicit type promotion rules
在两种情况下,都会发生有符号到无符号的转换,并且根据6.3.1.3很好地定义了这种转换:
否则,如果新类型是无符号的,则通过重复加或 比新类型可以表示的最大值多减去一个 直到该值在新类型的范围内。
意味着在以上两种情况下,都会生成相同的无符号值0xFFFFFFFF
。
答案 1 :(得分:2)
在此声明中
if(var != -1)
编译器需要确定操作数的通用类型。此过程称为常规算术转换。 来自C标准(6.5.9相等运算符)
4如果两个操作数都具有算术类型,则为常规算术 进行转换。...
相对于常规算术转换(C标准6.3.1.8常规算术转换)
否则,如果具有无符号整数类型的操作数具有等级 大于或等于另一个操作数类型的等级,然后 带符号整数类型的操作数将转换为 无符号整数类型的操作数。
因此,根据if语句表达式中的引号,将类型为int的整数常量-1
转换为类型为unsigned int的类型,即变量var
的类型,因为类型int和unsigned int具有相同的等级,变量var
的类型为unsigned int。
结果是条件产生错误。
答案 2 :(得分:-2)
int
(无论是带符号还是unsigned
)由一系列位表示,例如
B1B2 ... Bn
其中
Bi∈{0; 1}
现在,最大可表示的unsigned
int
看起来像
1111...1
但是,作为有符号值,-1表示为
1111...1
也是
因此1111 ... 1 == 1111 ... 1为真。转换为unsigned
并没有改变任何值,它改变了感知给定值的方式。就内存表示而言,2 ^(32-1)和-1实际上是同一个家伙,穿着不同的衣服。