c语言中int和short的行为

c语言中int和short的行为,c,int,output,short,C,Int,Output,Short,我想知道以下代码输出的原因: unsigned short a=10,aa=-1; if(a>-1) printf("surprise"); else printf(" No surprise"); 这给了输出“惊喜” 这使输出“毫不奇怪” 及 这使输出“毫不奇怪”以C语言指定的整数提升。基本上,算术是用有符号而不是短符号完成的。我假设您使用的是32位及以上的CPU unsigned short a=10,aa=-1; if(a>-1) printf("surpris

我想知道以下代码输出的原因:

unsigned short a=10,aa=-1;
if(a>-1)
  printf("surprise");
else 
  printf(" No surprise");
这给了输出“惊喜”

这使输出“毫不奇怪”


这使输出“毫不奇怪”

以C语言指定的整数提升。基本上,算术是用有符号而不是短符号完成的。我假设您使用的是32位及以上的CPU

unsigned short a=10,aa=-1;
if(a>-1)
  printf("surprise");
else 
  printf(" No surprise");
以上内容转化为下面的汇编。因此,您得到的是有符号int(10)与有符号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与0xFFFFFF进行无符号比较。对于第3部分,它将0x0A与0xFFFF进行有符号比较。您正在将无符号变量初始化为-1。无符号变量只能表示非负数。C不指定负号的表示形式,因此当您为无符号变量指定负数时,您将调用未定义的行为。此时,程序可以打印“惊喜”、“不惊喜”或“生日快乐”


在2s补码机(大多数现代CPU都是)上,-1与最大无符号值具有相同的位表示形式,因此很可能您已将aa初始化为最大可表示值。如果这是您真正想要的,那么您应该使用aa=USHRT\u MAX。

请参阅此堆栈交换问题:

在程序员的响应中,列出了完整的规则。 在第一种情况下,第四条规则适用(-1是有符号整数,它可以表示无符号短码的所有值,因此无符号短码将提升为有符号整数)。 在第二种情况下,第三条规则适用(有符号整数不能表示无符号整数的所有值,因此它被更改为无符号整数)。 在第三种情况下,将-1转换为无符号短字符,然后应用第一条规则


一般来说,我喜欢在进行任何比较之前将所有变量转换为相同的有符号类型(大到足以容纳我期望的范围),以避免混淆。

。如果希望成为一名开发人员,您需要能够解释这些事情。这些函数的输出没有任何意外--即使第一个示例的输出错误地表明不是这样。搜索“无符号整数溢出”和“整数提升”。输出与预期一致,但是,将未签名与已签名的-1进行比较是一种未定义的行为。如果计算机愿意,它有权从你的鼻子里射出绿色火花。
unsigned short a=10,aa=-1;
if(a>-1)
  printf("surprise");
else 
  printf(" No surprise");
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)