1

下面有两个循环。第一个效果很好,而第二个是无限循环。为什么?

for (unsigned int i=0; i<3; ++i)
{
    std::cout << "i= " << i << std::endl; // this gives proper result
}

for (unsigned int i=3; i>=0; --i)
{
    std::cout << "i= " << i << std::endl; // infinite loop
}
4

6 回答 6

12

Anunsigned int永远不能小于 0。这就是它的原因unsigned。如果你打开一些警告标志,你的编译器应该告诉你你的问题: 对于一个i >= 0总是正确unsigned的。

例如,Clang 根本不需要特殊的标志来警告:

example.cpp:5:29: warning: comparison of unsigned expression >= 0 is always true
      [-Wtautological-compare]
    for (unsigned int i=3; i>=0; --i)
                           ~^ ~
1 warning generated.

GCC 要求-Wextra

example.cpp: In function ‘int main()’:
example.cpp:5: warning: comparison of unsigned expression >= 0 is always true
于 2013-07-25T23:22:14.760 回答
3

其他答案(到目前为止)都是正确的;因为i是无符号的,i >= 0总是正确的,所以你有一个无限循环。

但这并没有告诉你如何解决它。如果您想遍历从 3 到 0 的无符号范围,似乎没有一种直接的方法可以做到这一点。除了更改i范围的类型或方向(可能有你不能这样做的原因)之外,你可以这样做:

for (unsigned int i=3; ; --i)
{
    std::cout << "i= " << i << std::endl;
    if (i == 0) break;
}

它不像简单的for循环那样干净,没有break,但它可以完成工作。

于 2013-07-25T23:28:37.993 回答
3

unsigned int不能小于零(这是循环条件检查的内容)。当i你的第二个循环从 0 递减时,它会环绕到UINT_MAX并且循环继续。

于 2013-07-25T23:22:49.110 回答
3

除了 Keith Thompson 的回答之外,还有另一种不需要break循环内部的编写方法:

for (unsigned int i = 3; i--; ) {
    std::cout << "i= " << i << std::endl;
}

请注意如何i--既作为终止条件又作为之后的条件,全部合二为一。后缀递减运算符的使用很重要,因为它保证您实际上执行了 3 次循环,从第一次迭代的 2 开始,到 0 结束,包括在内。

于 2013-07-25T23:59:22.213 回答
2

的最小值为unsigned int i0;其他任何东西都是负数,并且需要一个符号位,而这正是unsignedint 所没有的。

所以i >= 0总是会评估为真。

于 2013-07-25T23:23:57.530 回答
0

在您的第二个循环中,停止循环的条件是 i必须小于 0。的范围unsigned int0 to 65535。所以,这里unsigned int i不能小于零。因此,您的条件始终为真,因此循环变得无限。使用asigned int可以解决问题。

于 2013-07-26T08:55:39.473 回答