![](/img/trans.png)
[英]C - comparison between pointer and integer ('char *' and 'int')
[英]C comparison char and int
在下面的代码块中,7 的 if 语句中发生的隐式转换是什么? 我本来以为它最终会是 (0x98 <= 0x07) 但当条件计算为真并且 DoMyStuff 被调用时,情况并非如此。
char minstogo = 0x98;
if(minstogo <= 7) {
DoMyStuff();
}
每当你在两个不同类型的整数操作数之间有一个二元运算符( +
-
*
/
%
<<
>>
&
|
^
==
!=
<
<=
>
>=
之一)时,这两种类型会先转换为通用类型操作被执行。 决定转换类型的规则是(来自 C99 标准的第 6.3.1.8 节):
如果两个操作数具有相同的类型,则不需要进一步的转换。
否则,如果两个操作数都具有带符号的 integer 类型或都具有无符号的 integer 类型,则具有较小 integer 转换等级的操作数将转换为具有较大等级的操作数的类型。
否则,如果具有无符号 integer 类型的操作数的秩大于或等于另一个操作数类型的秩,则具有有符号 integer 类型的操作数将转换为具有无符号 integer 类型的操作数的类型。
否则,如果有符号integer类型操作数的类型可以表示无符号integer类型操作数类型的所有值,则将无符号integer类型操作数转换为有符号integer类型操作数类型。
否则,两个操作数都转换为无符号 integer 类型,对应于带符号 integer 类型的操作数的类型。
在这种情况下, char
可以是有符号或无符号的 integer 类型——它的符号是实现定义的。 不过,幸运的是,假设您使用的系统中char
是 8 位且int
至少是 16 位,则int
可以表示char
的所有可能值,无论char
是否带符号。
如果char
是有符号的,则适用上面的第二段,因此两个操作数都转换为int
(具有更高级别的类型;级别的定义方式有些复杂,但它本质上等同于该类型的位大小)。 由于 0x98 作为带符号的char
为负数,因此它被转换为 integer -104,然后小于 7。
相反,如果char
是无符号的,则适用第四段。 unsigned char
将作为int
转换为 152,它大于 7。
永远不要依赖char
被签名或未签名。 如果您需要具有特定符号的 8 位整数,请显式使用signed char
或unsigned char
,或使用 C99 类型int8_t
和uint8_t
,定义为 int <stdint.h>
。
很容易被 integer 促销规则引起的细微错误所困扰。 我强烈建议您始终使用-Wall
和 gcc 进行编译,这将警告您有符号整数和无符号整数之间的比较,这通常是导致错误的原因。
这里可能发生的情况是 char 是一个带符号的值,因此 0x98 注册为负数。 因此它小于 7
同样在这种情况下,7 将在 go 下不进行转换。 相反,char 将被扩展为与 7 相同的整数类型,然后进行比较。
0x98 是 152。
由于您声明了“char”而不是“unsigned char”,因此您试图将 152 分配给范围为-128 - 127的类型。
这将溢出,并给你一个负数,它将 < 7 (0x07)。
将 chars 表示为八位字节,将 minstogo 设置为 0x98 是二进制值 10011000。设置了符号位,它是一个负值 integer。 您可能需要一个 unsigned char 以便测试评估为 false。
它的计算结果与0x98 <= 7
相同,除非平台的char
类型默认为有符号且CHAR_BIT
为 8。在这种情况下, minstogo
的值为负且minstogo <= 7
为真。
使用当前设置的编译器,char 是有符号类型:并且因为设置了其值的高位 (0x80),所以该值为负。 当 minstogo 被加宽时,该负号被保留(通过符号扩展),因此 minstogo 被加宽为小于 7 的负值 integer(例如 0xFF98)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.