代码之家  ›  专栏  ›  技术社区  ›  user3139545

具有无符号字符的for循环产生意外行为

c++
  •  4
  • user3139545  · 技术社区  · 6 年前

    我在练习面试问题,但我很难回答这个基本问题:

    这个循环将执行多少次?

      unsigned char half_limit = 150;
    
      for (unsigned char i = 0; i < 2 * half_limit; ++i)
      {
          std::cout << i;
      }
    

    我的想法是,由于一个无符号int只达到255,它将永远执行,因为当我增加一个无符号字符时,当它达到255时,它将恢复为0?然而,这种想法是错误的,更奇怪的是,这是cout给我的输出:

     !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~���������������������������������������������������������������������������������������������������������������������������������    
    

    当我试图用以下方式限制外观时:

    if (i <= 255)
      std::cout << i;
    else
      break;
    

    循环仍然是无限的。

    我的问题是,代码的预期结果是什么,为什么会这样?

    2 回复  |  直到 6 年前
        1
  •  8
  •   taskinoor    6 年前

    这是一个无限循环。让我们一步一步地看一下:

    2 * half_limit

    half_limit unsigned char 但是 2 int . 所以 half\u限制 被提升为 内景 结果是整数 300 .

    i < 2 * half_limit

    因为右手的尺寸是 内景 , i 也被提升为 内景 . 这里没有问题。

    但在 ++i 不涉及促销,并且 是一个 无符号字符 如声明所示。所以在达到 255 它可以追溯到 0 以及条件 <2*half\u限制 总是正确的 永远不会达到 300 .

    第二种情况也是一样的 if (i <= 255) 返回到 0 在进行此检查之前。

        2
  •  2
  •   Minor Threat    6 年前

    如果需要,C/C++会扩展表达式的位容量。它叫 Integer type promotion .

    根据这些规则, half_limit * 2 正在升级为整数值300。假设 CHAR_BIT == 8 , i 是一个八位元,因此它永远不会达到300,因此循环将永远持续。此外,无符号八位字节总是小于或等于255,因此它是 if 表达式是多余的。