在下面的代码块中,if语句中发生的impicit转换是什么?我会虽然它会最终成为(0x98 < = 0x07)但这不是什么情况发生,因为条件评估为真,并且DoMyStuff被调用。C比较char和int
char minstogo = 0x98;
if(minstogo <= 7) {
DoMyStuff();
}
在下面的代码块中,if语句中发生的impicit转换是什么?我会虽然它会最终成为(0x98 < = 0x07)但这不是什么情况发生,因为条件评估为真,并且DoMyStuff被调用。C比较char和int
char minstogo = 0x98;
if(minstogo <= 7) {
DoMyStuff();
}
每当你有一个二进制运算符(的+
-
*
/
%
<<
>>
&
|
^
==
!=
<
<=
>
>=
一个)的不同类型的两个之间整型操作数,这两种类型的操作之前转换成通用型被执行。决定转换类型的规则(从C99标准的6.3.1.8节):
如果两个操作数具有相同的类型,则不需要进一步的转换。否则,如果两个操作数具有有符号整数类型或两者都具有无符号整数类型 ,则类型为较小整数转换等级的操作数为 转换为具有较高等级的操作数的类型。
否则,如果具有无符号整数类型的操作数的秩大于或 等于另一个操作数的类型的秩,然后用 符号整型操作数被转换为操作数的类型与无符号 整数类型。
否则,如果用符号整型操作数的类型可以表示 所有与无符号整数类型的操作数的类型的值,则 与无符号整数类型的操作数被转换到 的类型带有符号整数类型的操作数。
否则,两个操作数转换为对应于与符号整型操作数的类型的无符号整数类型 。
在这种情况下,char
可能是有符号或无符号整数类型 - 其签名是实现定义的。幸运的是,int
可以代表char
的所有可能值,不管char
是否被签名,假设您位于系统中,其中char
s是8位而int
s是至少16位。
如果char
被签名,则上面的第二个段适用,所以这两个操作数被转换为int
(具有较高等级的类型;秩以稍微复杂的方式定义的,但它基本上等效于类型的比特大小)。 0x98在全局以来,作为有符号char
,为负时,它转化为整数-104,然后将其小于7
如果相反char
是无符号的,则第四段适用代替。未签名的char
将被转换为152,作为大于7的int
。
永远不会依赖于char
被签名或未签名。如果您需要某种符号的8位整数,请明确使用signed char
或unsigned char
,或使用定义为int <stdint.h>
的C99类型int8_t
和uint8_t
。
由整数提升规则引起的微妙错误很容易被咬伤。我强烈建议你总是用gcc编译-Wall
,它会警告你有关有符号和无符号整数之间的比较,这通常是错误的原因。
这里可能发生的情况是char是一个有符号值,0x98因此注册为负数。因此它小于7
也在这种情况下,7将不会转换。相反,char将被扩展为与7相同的整型,然后进行比较。
使用你的编译器及其当前设置,char是一个带符号的类型:并且由于其值的高位(0x80)被设置,所以该值为负。当minstogo变宽,即负号被保留(通过符号扩展)等minstogo被加宽到负整数(例如0xFF98),这是小于7
是0x98在全局152
由于你已经声明了一个“char”而不是“unsigned char”,你试图将152赋给一个范围为-128 - 127的类型。
这将溢出,并给你一个负数,这将是< 7(0x07)。
将字符表示为一个八位字节,将minstogo设置为0x98是一个二进制值10011000.符号位被设置,它是一个负整数值。你可能需要一个unsigned char来让测试评估为false。
它将同0x98 <= 7
,除非该平台的char
类型默认评估,以签署和CHAR_BIT
是8。在这种情况下,的minstogo
值将是负值,minstogo <= 7
将是真实的。
它有一个实现定义的标志。有时它是在某些主机上签名的,有时(在其他主机上)则不是。 – 2009-06-18 01:26:17