【问题标题】:Using the == operator to compare a char to 0x80 always results in false?使用 == 运算符将 char 与 0x80 进行比较总是会导致 false?
【发布时间】:2013-07-24 13:19:40
【问题描述】:
char byte = 0x80
if(byte == 0x80)
{
    cout << "This message never gets printed!";
}

十六进制值0x80在二进制中等效于1000 0000,显然适合一个字节。

但是,编译器会警告我带有条件的行:

warning: comparison is always false due to limited range of data type

为什么在这种情况下条件为假的结果?

0x80 是否在条件中扩展为 0x80000000 之类的东西?

是否可以使用== 运算符来检查char 是否等于0x80

【问题讨论】:

  • char 可以签名也可以不签名。
  • 是的。但是即使0x80解析为负数,我们不只是比较char的内容是否等于字面量吗?如果不是,请解释! :)
  • @CoryKlein: 0x80int
  • 这让我之前。很烦人。
  • 更烦人的是,这种比较实际上会在某些架构上返回 true,而在其他架构上返回 false。因此,在为不同的平台编译时,正在运行的代码会突然中断。就我而言,编译器没有像你一样发出警告。

标签: c++ types binary char byte


【解决方案1】:

signed char 类型可以包含值 0x7f-0x80,总共 256 个值。 unsigned char 类型可以包含值0x80,因为最大值是0xff。您正在使用的char 类型的实现似乎是signed char 类型。

0x80 分配给signed char 会强制值溢出,使值变为-0x80signed char 类型不能向系统表示0x80,因为它总是被解释为-0x80。这是因为最高有效位用作符号位。

如果您使用按位和:byte &amp; 0x80,您的比较可能会成功。请注意,此操作的结果并不意味着在任一方向上都相等,而只是是否设置了最高有效位。

【讨论】:

  • char 类型可以有符号也可以无符号,所以你的第一句话并不总是正确的。
  • &amp; 的测试不等于相等。
  • @DavidRodríguez-dribeas 正确。即使byte 不包含0x80byte &amp; 0x80 也可以评估为真。例如,0x80 &amp; 0x81 的计算结果为 true。
  • 会溢出,但是值会是-128,不是-1!
【解决方案2】:

问题在于 char 在 C 和 C++ 标准中定义为可以是有符号或无符号值,并且 char 必须至少有 8 位。有问题的体系结构和编译器似乎使用带符号的 8 位 char 值。

这意味着任何最高位(第 7 位)的值都是负值。所以 0x80 作为 char 变为 -128 十进制。

常量 0x80 不是char 值,它是int 值。

因此,当您将 -128 与 0x80 (128) 进行比较时,它们并不相同,而且永远不可能相同,编译器会发现这一点并发出警告。

有多种方法可以实现这一点,这里有几种可能的场景:

首先,我们可以将其中一个值转换为另一个值的类型:

if (((int)byte) & 0xff == 0x80)

if (byte == (char)0x80) 

或者,我们可以将常量设为char 值,而不是int 值。

if (byte == '\200')     // Octal 200 = 0x80. 

if (byte == '\x80')

或者,使用unsigned char byte = 0x80; - 指定它是一个无符号字符将确保它不会“翻转为负数”。

【讨论】:

  • 为了完整起见,我要补充一点,您还可以使用 -funsigned-char 编译(至少在 clang 和 gcc 下),这将强制所有 chars 未签名。
猜你喜欢
  • 2012-05-29
  • 2013-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多