int main(void)
{
unsigned int y = 10;
int x = – 4;
if (x > y)
Printf("x is greater");
else
Printf("y is greater");
getch();
return (0);
}
Output: x is greater
我认为输出y会更大,因为它是无符号的。这背后的原因是什么?
答案 0 :(得分:45)
因为int
值被提升为unsigned int
。特别是{32}计算机上的0xFFFFFFFC
,unsigned int
为4294967292
,远大于10
C99 6.3.1.1-p2
如果int可以表示原始类型的所有值(由宽度限制,对于位字段),则该值将转换为int;否则,它将转换为 unsigned int 。这些被称为整数促销。所有其他类型都不会被整数促销更改。
执行转换:
C99 6.3.1.3-p2
否则,如果新类型是无符号的,则通过重复地添加或减去一个可以在新类型中表示的最大值来转换该值,直到该值在新类型的范围内。
这基本上意味着“添加UINT_MAX + 1”(正如我所读到的那样)。
关于晋升为unsigned int
方面的原因;的优先级:
C99 6.3.1.8-p1
...否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的等级,则带有符号整数类型的操作数将转换为具有无符号整数的操作数的类型类型。
否则,如果带有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值,则具有无符号整数类型的操作数将转换为带有符号整数的操作数的类型类型。
它告诉我int
与unsigned char
应该按预期工作。
<强>测试强>
int main()
{
int x = -4;
unsigned int y = 10;
unsigned char z = 10;
if (x > y)
printf("x>y\n");
else
printf("x<y\n");
if (x > z)
printf("x>z\n");
else
printf("x<z\n");
return 0;
}
<强>输出强>
x>y
x<z
好好看看。
答案 1 :(得分:11)
有符号和无符号值之间的比较将在“无符号空格”中进行。即,通过添加UINT_MAX + 1
,有符号值将转换为无符号值。在使用2补码表示负值时,在引擎盖下不需要对值进行特殊处理。
在此示例中,-4
变为0x100000000-4
= 0xFFFFFFFC
,显然是> 10
。
答案 2 :(得分:4)
比较C中的两个值时,它们必须属于同一类型。在这种情况下(int
和unsigned int
),int
值将首先转换为unsigned int
。
其次,C中的无符号整数运算以模数+ 1的最大值为模(即,它“循环”,因此UINT_MAX + 1
再次为0
,反之亦然)。因此,将负值转换为无符号的结果非常大。
标准中的相关部分说:
6.3.1.3有符号和无符号整数
2
否则,如果新类型是无符号的,则通过重复添加或转换该值 减去一个可以在新类型中表示的最大值 直到该值在新类型的范围内。
答案 3 :(得分:3)
当您比较int
和unsigned int
时,int
会转换为unsigned int
。
将int
转换为unsigned int
是通过添加UINT_MAX+1
来完成的(请注意,您的int
为否定)。所以实际上你在比较:
if (-3 + UINT_MAX > 10) //Since -4 is converted to UINT_MAX+1-4
这是真的。
答案 4 :(得分:1)
int值的第一位用于定义它是正数还是负数。 (1 =负数,0正数) 在比较之前,您的两个变量都会被转换为unsigned int,其中第一位中的1将被解释为您的数字的一部分。
此代码应该可以正常工作:
int main(void)
{
unsigned int y = 10;
int x = – 4;
if (x > (int) y)
Printf("x is greater");
else
Printf ("y is greater");
getch ( );
return (0);
}
答案 5 :(得分:-2)
int x = -4(2的2的补码是1111 1100 = 252),无符号的y y = 10是(0000 1010 = 10)所以252> 10所以-4大于10.