下面有两个循环。第一个效果很好,而第二个是无限循环。为什么呢?
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
}
答案 0 :(得分:12)
unsigned int
永远不会小于0.这就是无符号的原因。如果你打开一些警告标志,你的编译器应该告诉你你的问题:对于i >= 0
值,unsigned
始终为真。
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
答案 1 :(得分:3)
unsigned int
不能小于零(这是循环的条件正在检查)。当第二个循环中的i
从0递减时,它会回绕到UINT_MAX
并且循环继续。
答案 2 :(得分: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
循环一样干净,但它能完成这项工作。
答案 3 :(得分:3)
除了Keith Thompson的回答之外,还有另一种方法可以编写它,在循环中不需要break
:
for (unsigned int i = 3; i--; ) {
std::cout << "i= " << i << std::endl;
}
注意i--
如何作为终止条件和作为后续行为,一体化。使用postfix减量运算符非常重要,因为它可以保证你实际执行循环3次,从第一次迭代的2开始到0结束,包括在内。
答案 4 :(得分:2)
unsigned int i
的最小值为0;其他任何东西都是负面的,需要一个符号位,具体是unsigned
int不具备的。
因此i >= 0
将始终评估为真。
答案 5 :(得分:0)
在第二个循环中,停止循环的条件是i
必须小于0. unsigned int
的范围是0 to 65535
。所以,这里unsigned int i
不能小于零。所以,你的情况总是正确的,因此循环变得无限。使用signed int
可以解决问题。