将无符号整数变量转换为有符号变量

conversion of unsigned integer variable to signed variable

为什么下面的程序给出的输出是 b 大于 a? 即使 b 包含 -2.

void main()
{
    unsigned int a=12;
    int b=-2;

    if(a>b)
        printf("a is greater");
    else
        printf("b is greater");

    getch();
}

首先,引用关系运算符的 C11 标准,第 6.5.8 章

If both of the operands have arithmetic type, the usual arithmetic conversions are performed.

现在,按照第6.3.1.8章的描述,普通算术转换,如果你尝试在signed和[=12=之间进行算术运算] 整数(类型),signed 将被提升为 unsigned 类型(更高级别),然后进行操作。

所以,在这里,为了进行比较,b 的值被转换为 unsigned 类型,并且您在那里得到 错误的 输出.

引用相关部分,出自同一章节

[...] Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

你也可以查看常用的算术提升规则here

也就是说,void main() 应该是 int main(int argc, char* argv[]),或者至少是 int main(void)

这是类型提升规则之一:如果一个参数是 int,另一个参数是 unsigned int,则 int 被提升为 unsigned int,添加UINT_MAX + 1 如有必要。

这发生在比较之前。

 if(a>b)

这里aunsigned intbsigned int,所以由于隐式转换,b会被转换成unsigned int typeb会有很大的值(不用说,会大于a)。

因此,你得到了意想不到的结果。

According to C99- 6.3.1.8 Usual arithmetic conversions

[...]

3.Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

要执行比较,首先将两个操作数转换为同一类型。在这种情况下,int b 将转换为更高排名的 unsigned。对于比较值,则为12 > (-2 + (UINTMAX + 1))?这是错误的。

通常数学意义上的比较:

unsigned int a;
int b;

if ((b < 0) || (a > b)) printf("a is greater");