在下面的代码块中,7语句的if语句中发生的impicit转换是什么?虽然它会最终成为(0x98< = 0x07),但是当条件评估为真并且调用DoMyStuff时,情况并非如此。
char minstogo = 0x98;
if(minstogo <= 7) {
DoMyStuff();
}
答案 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位整数,请明确使用char
或signed char
,或使用C99类型unsigned char
和int8_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)。