繁体   English   中英

C 比较char和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 charunsigned char ,或使用 C99 类型int8_tuint8_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM