【问题标题】:Char comparison with 0xFF returns false even when it is equal to it, why?字符与 0xFF 的比较即使等于它也会返回 false,为什么?
【发布时间】:2017-11-29 21:34:15
【问题描述】:

在 C++ 程序中,我有一些 char buf[256]。问题出在这里:

if (buf[pbyte] >= 0xFF)
    buf[++pbyte] = 0x00;

即使buf[pbyte] 等于 255 AKA 0xFF,这也总是返回 false,如在即时窗口和监视窗口中所见。因此该语句不会被执行。但是,当我将其更改为以下时:

if (buf[pbyte] >= char(0xFF))
    buf[++pbyte] = 0x00;

程序有效;怎么来的?

【问题讨论】:

  • 根据 C++ 语言规范,char 类型的最大保证范围为 255。不能有大于最大值的值。
  • char 通常介于 -128 和 +127 之间。赔率很好,它永远无法达到 255。
  • 我第一次使用 == 然后我使用 >= 但没有帮助。最终我自己使用了 char(0xFF) 而不是 0xFF。似乎当 0xFF 被视为 int 而不是转换为 char 时,代码会失败。如果我将 0xFF 转换为 char 则无论我使用 >= 还是 == 都有效
  • 好的,但是 char 中的 -1 将是 0xFF 不是设置了所有位吗?为什么0xFF不被视为-1?我在这里错过了什么?
  • 原始 0xFF 是 int。 255 对于int 来说就可以了。

标签: c++ char int


【解决方案1】:

问题是char 已在您的系统上签名。

在常见的 2s 补码表示中,带有“字节值”0xFF 的有符号 char 表示整数 -1,而 0xFF 是带有值 255 的 int。因此,您实际上是在比较 @ 987654326@,产生错误。请记住,由于算术转换规则,它们被比较为int,也就是说,在比较之前,两个操作数都被提升(“隐式转换”)为int

但是,如果您写 char(0xFF),您最终会得到比较 -1 >= -1,结果如预期的那样为 true。

如果要存储 [0,255] 范围内的数字,则应使用 unsigned charstd::uint8_t 而不是 char

【讨论】:

  • 问题是代码没有考虑到char被签名的可能性。 ;-)
【解决方案2】:

文字 0xFF 被视为值为 255 的 int

当您将charint 进行比较时,char 在比较之前被提升为int

在某些平台上,char 是一个有符号值,范围为 -128 到 +127。在其他平台上,char 是一个无符号值,范围为 0 到 255。

如果您平台的 char 已签名,并且其位模式为 0xFF,那么它可能为 -1。由于 -1 是有效的int,因此促销活动到此停止。

你最终会比较 -1 和 255。

解决方案是消除隐式转换。您可以将比较写为:

if (buf[pbyte] == '\xFF') ...

现在双方都是chars,所以晋升方式相同,直接可比。

【讨论】:

  • “如果你的平台的 char 是有符号的,并且它的位模式是 0xFF,那么它就是 -1。” 这是定义的实现。
  • @Baum mit Augen:好的,我添加了对冲词“可能”来解决这个问题。然而,char 受到当前标准的限制,以至于实现只能使用二进制补码。 (例如,有符号幅度只能表示 -127 到 127,但标准要求范围至少为 256 个不同的值。)
  • 我相信 [-127,127] 在 C++98 中是合法的。虽然可能是错的。不管怎样,现在没事了。 :)
【解决方案3】:

默认情况下,整数文字转换为int,假设该值适合int 类型,否则将提升为long

因此,在您的代码中,您指定 0xFF,它被解释为 int 类型,即 0x000000FF

【讨论】:

    【解决方案4】:

    由于这种情况下的整数促销

    if (buf[pbyte] >= `0xFF`)
    

    这两个操作数被转换为int 类型(更准确地说,只有左操作数被转换为int 类型的对象,因为右操作数已经具有int 类型)。在您的系统中,char 类型的行为与signed char 类型一样,然后'\xFF' 的值是等于-1 的负值。然后把这个值转换成int类型的对象,你会得到0xFFFFFFFF(假设int类型占用4个字节)。

    另一方面,整数常量0xFF 是一个正值,其内部表示形式类似于0x000000FF

    因此 if 语句中的条件

    if ( 0xFFFFFFFF >= `0x000000FF`)
    

    结果为假。

    当您使用转换 ( char )0xFF 时,两个操作数具有相同的类型和相同的值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-03-09
      • 1970-01-01
      • 2015-04-12
      • 1970-01-01
      • 2021-08-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多