我想知道输出以下代码的原因是什么:
unsigned short a=10,aa=-1;
if(a>-1)
printf("surprise");
else
printf(" No surprise");
这会输出“Surprise”
unsigned int a=10,aa=-1;
if(a>-1)
printf("surprise");
else
printf("No surprise");
这会输出“No Surprise”
和
unsigned short a=10,aa=-1;
if(a>aa)
printf("surprise");
else
printf("No surprise");
这给输出“No Surprise”
答案 0 :(得分:2)
用C语言指定的整数提升。基本上,算术是在有符号而不是短的情况下完成的。我假设您使用32位及以上的CPU。
unsigned short a=10,aa=-1;
if(a>-1)
printf("surprise");
else
printf(" No surprise");
以上翻译成下面的汇编。所以,你得到的是signed int(10)与signed int(-1)的比较,如汇编程序使用jle指令所示。
unsigned short a=10,aa=-1;
000C17DE mov eax,0Ah
000C17E3 mov word ptr [a],ax
000C17E7 mov eax,0FFFFh
000C17EC mov word ptr [aa],ax
if(a>-1)
000C17F0 movzx eax,word ptr [a]
000C17F4 cmp eax,0FFFFFFFFh
000C17F7 jle wmain+52h (0C1812h)
对于第2部分,无符号比较0x0A和0xFFFFFFFF。对于第3部分,它签名比较0x0A和0xFFFF
答案 1 :(得分:2)
请参阅此Stack Exchange问题:
在AProgrammer的回复中,列出了完整的规则。 在第一种情况下,第4个规则适用(-1是有符号整数,它可以表示无符号short的所有值,因此unsigned short被提升为有符号整数)。 在第二种情况下,应用第3个规则(有符号整数不能表示无符号整数的所有值,因此它将更改为无符号整数)。 在第三种情况下,-1将转换为unsigned short,然后应用第一个规则。
一般来说,我喜欢在进行任何比较之前将所有变量转换为相同的有符号类型(大到足以保持我期望的范围),从而避免混淆。
答案 2 :(得分:1)
您正在将无符号变量初始化为-1。无符号变量只能表示非负数。 C没有指定用于负数有符号数的表示,因此当您指定无符号变量的负数时,将调用未定义的行为。此时,该程序可以打印“惊喜”,“不出意外”或“生日快乐”。
在2s补码机器(大多数现代CPU都是)上,-1具有与最大无符号值相同的位表示,因此您可能已将aa初始化为最大可表示值。如果这是你真正想要的,你应该使用aa = USHRT_MAX。