C比较char和int

时间:2009-06-18 01:18:11

标签: c

在下面的代码块中,7语句的if语句中发生的impicit转换是什么?虽然它会最终成为(0x98< = 0x07),但是当条件评估为真并且调用DoMyStuff时,情况并非如此。

char minstogo = 0x98;
if(minstogo <= 7) {
   DoMyStuff();
}

6 个答案:

答案 0 :(得分:16)

每当你有一个二元运算符(+ - * / % << >> {{1 }} & | ^ == != < <= >)两个不同类型的整数操作数之间,在执行操作之前,将两种类型转换为通用类型。决定转换为类型的规则是(来自C99标准的第6.3.1.8节):

  

如果两个操作数具有相同的类型,则不需要进一步转换。

     

否则,如果两个操作数都有有符号整数类型或两者都有无符号   整数类型,具有较小整数转换等级类型的操作数是   转换为具有更高等级的操作数的类型。

     

否则,如果具有无符号整数类型的操作数的等级大于或等于   等于另一个操作数的类型的等级,然后是操作数   有符号整数类型转换为带有unsigned的操作数的类型   整数类型。

     

否则,如果带有符号整数类型的操作数的类型可以表示   那么,带有无符号整数类型的操作数类型的所有值   具有无符号整数类型的操作数将转换为该类型   带有符号整数类型的操作数。

     

否则,两个操作数都将转换为无符号整数类型   对应于带有符号整数类型的操作数的类型。

在这种情况下,>=可以是有符号或无符号整数类型 - 其签名是实现定义的。幸运的是,char可以表示int的所有可能值,无论char是否已签名,假设您所在的系统char为8位和char至少为16位。

如果int已签名,则上述第二段适用,因此两个操作数都转换为char(排名较高的类型;排名以某种复杂的方式定义,但它基本上相同到类型的位大小)。由于0x98(作为带符号的int)是负数,因此它被转换为整数-104,然后小于7。

如果char是无符号的,则应用第四段。未签名的char将转换为152 char,大于7。

不要依赖int被签名或未签名。如果您需要某个签名的8位整数,请明确使用charsigned char,或使用C99类型unsigned charint8_t,定义为int uint8_t

很容易被整数提升规则引起的细微错误所困扰。我强烈建议您始终使用gcc编译<stdint.h>,这将警告您有符号和无符号整数之间的比较,这通常是导致错误的原因。

答案 1 :(得分:6)

这里可能发生的是char是一个带符号的值,因此0x98注册为负数。因此它小于7

同样在这种情况下,7将不会转换。相反,char将被扩展为与7相同的整数类型,然后进行比较。

答案 2 :(得分:1)

将字符表示为8位字节,将minstogo设置为0x98是二进制值10011000.符号位置位,它是负整数值。您可能需要一个unsigned char,以便测试评估为false。

答案 3 :(得分:1)

除非平台的0x98 <= 7类型默认为已签名且char为8,否则它将与CHAR_BIT进行评估。在这种情况下,minstogo的值将为负数并且minstogo <= 7将是真的。

答案 4 :(得分:0)

使用编译器及其当前设置,char是有符号类型:并且因为其值的高位(0x80)已设置,该值为负。当minstogo被加宽时,该负号将被保留(通过符号扩展),因此minstogo被加宽为负整数(例如0xFF98),小于7。

答案 5 :(得分:0)

0x98是152。

由于您已声明了“char”,而不是“unsigned char”,因此您尝试将152分配给范围为-128 - 127的类型。

这会溢出,并给你一个负数,这将是&lt; 7(0x07)。