下面有两个循环。第一个效果很好,而第二个是无限循环。为什么?
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
}
下面有两个循环。第一个效果很好,而第二个是无限循环。为什么?
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
}
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
其他答案(到目前为止)都是正确的;因为i
是无符号的,i >= 0
总是正确的,所以你有一个无限循环。
但这并没有告诉你如何解决它。如果您想遍历从 3 到 0 的无符号范围,似乎没有一种直接的方法可以做到这一点。除了更改i
范围的类型或方向(可能有你不能这样做的原因)之外,你可以这样做:
for (unsigned int i=3; ; --i)
{
std::cout << "i= " << i << std::endl;
if (i == 0) break;
}
它不像简单的for
循环那样干净,没有break
,但它可以完成工作。
unsigned int
不能小于零(这是循环条件检查的内容)。当i
你的第二个循环从 0 递减时,它会环绕到UINT_MAX
并且循环继续。
除了 Keith Thompson 的回答之外,还有另一种不需要break
循环内部的编写方法:
for (unsigned int i = 3; i--; ) {
std::cout << "i= " << i << std::endl;
}
请注意如何i--
既作为终止条件又作为之后的条件,全部合二为一。后缀递减运算符的使用很重要,因为它保证您实际上执行了 3 次循环,从第一次迭代的 2 开始,到 0 结束,包括在内。
的最小值为unsigned int i
0;其他任何东西都是负数,并且需要一个符号位,而这正是unsigned
int 所没有的。
所以i >= 0
总是会评估为真。
在您的第二个循环中,停止循环的条件是 i
必须小于 0。的范围unsigned int
是0 to 65535
。所以,这里unsigned int i
不能小于零。因此,您的条件始终为真,因此循环变得无限。使用asigned int
可以解决问题。