unsigned int导致循环为无穷大

unsigned int causes infinite for-loop

本文关键字:无穷大 循环 int unsigned      更新时间:2023-10-16

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

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
}

unsigned int永远不能小于0。这就是它无符号的原因。如果打开一些警告标志,编译器应该告诉您问题:对于unsigned值,i >= 0总是true

例如,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

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

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

但这并不能告诉你如何修复它。如果你想在一个从3到0的无符号范围内迭代,似乎没有一个简单的方法。除了改变i的类型或范围的方向(可能有一些原因你不能这样做),你可以这样做:

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

它不像没有break的简单for循环那样干净,但它完成了任务。

除了Keith Thompson的答案之外,还有另一种编写方法不需要在循环中使用break

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

请注意i--是如何同时作为终止条件和事后思考的。后缀递减运算符的使用很重要,因为它可以保证实际执行循环3次,从第一次迭代的2开始,到0结束,包括在内。

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

所以i >= 0的值总是为true。

在第二个循环中,停止循环的条件是i必须小于0。CCD_ 19的范围为CCD_。所以这里unsigned int i不能小于零。所以,你的条件总是成立的,结果循环变成了无穷大。使用signed int可以解决这个问题。