无符号整数和有符号整数的比较运算

无符号整数和有符号整数的比较运算

请看下面的代码片段

int main(){ 
 unsigned int a = 1000;
 int b = -1;
 if (a>b) printf("A is BIG! %d\n", a-b);
 else printf("a is SMALL! %d\n", a-b); 
 return 0;}

这就给出了输出:a很小:1001。

我不明白这里发生了什么。>操作符在这里是如何工作的?为什么“a”比“b”小?如果它确实较小,为什么我得到一个正数(1001)作为区别?


慕婉清6462132
浏览 1335回答 3
3回答

森栏

在一个典型的实现中int转换为unsigned int是4,294,967,295,确实是≥1000。即使你把减法用unsigned世界,1000 - (4,294,967,295) = -4,294,966,295 = 1,001这就是你得到的。怪不得gcc当你比较的时候会发出警告unsigned带着signed..(如果您没有看到警告,请传递-Wsign-compare(国旗)

qq_笑_17

您正在进行无符号比较,即比较1000到2^32-1。输出是由printf中的%d签名的。注:有时,混合有符号操作数和无符号操作数的行为是特定于编译器的。我认为最好是避开他们,在有疑问的时候施展拳脚。

缥缈止盈

在由所谓的“公共”类型定义的“公共”类型中执行不同整数类型之间的二进制操作。常用算术变换(见语言规范6.3.1.8)。在您的例子中,“公共”类型是unsigned int..这意味着int操作数(您的b)将被转换为unsigned int之前的比较,以及为执行减法的目的。什么时候-1转换为unsigned int结果是最大的可能。unsigned int价值(与UINT_MAX)。不用说,它会比你没有签名的要大。1000价值,意思是a > b确实是假的a确实是小的相比较(unsigned) b..这个if在您的代码中,应该解析为else分支,这就是你在实验中观察到的。同样的转换规则也适用于减法。你的a-b实际上被解释为a - (unsigned) b结果有类型unsigned int..这样的值不能用%d格式说明符,因为%d只与签名价值。你想用%d结果是未定义的行为,所以从C语言的角度来看,打印的值(尽管在实践中具有逻辑确定性的解释)是完全没有意义的。编辑:实际上,我可能弄错了未定义的行为部分。根据C语言规范,对应的有符号整数类型和无符号整数类型范围的共同部分应具有相同的表示形式(根据脚注31,“作为函数的参数的互换性”)。所以,结果a - b表达式未签名。1001如前所述,除非我遗漏了一些东西,否则使用以下方法打印这个特定的无符号值是合法的%d说明符,因为它属于int..印刷(unsigned) INT_MAX + 1带着%d是个未知数,但是1001u都没问题。
打开App,查看更多内容
随时随地看视频慕课网APP