以下程序会产生意外结果
#include <iostream>
using namespace std;
int main() {
for(unsigned int i = 10; i >= 0; i--)
{
cout << i << endl;
}
return 0;
}
但将unsigned int
更改为int
会得到输出10,9,8 ...,0
拥有unsigned int
并使用它来遍历值[n,0](含)的正确方法是什么?我迭代数组的每个元素,但不想使用foreach语法,因为我需要一个变量来保存元素的位置。
答案 0 :(得分:3)
无符号变为负数,不正确。无符号算术运算会回绕,因此在无符号算术运算中,如果从零减去1,则将得到最大的无符号值。这是什么取决于您的编译器,但是如果您具有32位整数,则为4294967295。
我不认为您的程序应该崩溃,我认为它应该永远循环,因为在无符号算术i >= 0
中总是正确的。
顺便说一句,我编写该循环以使其正确使用无符号算术的方式是
for (unsigned int i = 11; i-- > 0; )
{
cout << i << endl;
}
答案 1 :(得分:1)
如果程序崩溃,则表明编译器有缺陷。
将unsigned
减少为零会产生该类型的最大数目。
成语
for (unsigned i = 11; i-->0; )
(当与您出现的循环体一起使用时,将输出整数10, 9, ..., 0
)
unsigned
类型时经常使用。 -->
本身并不是真正的运算符,因为它被解析为两个单独的标记--
和>
,但有时也称为 slide运算符,特别是像我这样的老年人。
答案 2 :(得分:1)
我认为您的困惑与for循环的运作方式有关。在这里您可以找到description。重要的细节是了解每次循环
for (init_statement; condition; iteration_expression){ statement;}
正在运行,操作顺序等效于以下内容:
{ init_statement while ( condition ) { statement iteration_expression ; } }
这意味着在{strong> 循环块执行后,i
会减小。
对于int
,当i = 0
时,它将运行其中的代码,然后减小该值。这样,循环的下一次迭代将使条件失败,因此它不会显示i = -1
。
关于unsigned int
,它永远不会变成负数。如果您对其进行调试,则将看到它达到0时如何将值转换为无符号值而不是值-1,而结果是一个很大的正值。特别是如果unsigned int
为32位,则为4294967295。您可以查看详细信息in this other question。
这就是为什么您具有“意外行为”(不适用于编译器)的原因,因为突然间您有一个非常大的正数,因此您手中可能会有无限循环。