C ++ for循环中的无符号整数

时间:2012-01-28 08:54:50

标签: c++ for-loop unsigned-integer

我在Stackoverflow上对C ++中的反向循环进行了一些研究,它使用无符号整数而不是有符号整数。但我仍然不明白为什么会出现问题(见Unsigned int reverse iteration with for loops)。为什么以下代码会产生分段错误?

#include <vector>
#include <iostream>
using namespace std;

int main(void)
{
    vector<double> x(10);

    for (unsigned int i = 9; i >= 0; i--)
    {
        cout << "i= " << i << endl;
        x[i] = 1.0;
    }

    cout << "x0= " << x[0] << endl;

    return 0;
}

我明白问题是当索引i等于零时,因为有类似溢出的东西。但我认为无符号整数可以取零值,不是吗?现在,如果我用有符号整数替换它,那绝对没有问题。

有人能用无符号整数向我解释反向循环背后的机制吗?

非常感谢!

5 个答案:

答案 0 :(得分:25)

这里的问题是无符号整数永远不会为负。

因此,循环测试:

i >= 0

永远是真的。因此,你得到一个无限循环。

当它低于零时,它会回绕到最大值unsigned
因此,您还将访问x[i]越界

对于有符号整数,这不是问题,因为它只会变为负数,从而导致i >= 0失败。

因此,如果要使用无符号整数,可以尝试以下方法之一:

for (unsigned int i = 9; i-- != 0; )

for (unsigned int i = 9; i != -1; i--)

这两个是由GManNickG和AndreyT在评论中提出的。


这是我最初的3个版本:

for (unsigned int i = 9; i != (unsigned)0 - 1; i--)

for (unsigned int i = 9; i != ~(unsigned)0; i--)

for (unsigned int i = 9; i != UINT_MAX; i--)

答案 1 :(得分:6)

问题是,你的循环允许i低至零,并且只有当i小于0时才期望退出循环。因为我是无符号的,它永远不会小于0.它会翻到2 ^ 32-1。这大于矢量的大小,因此导致段错误。

答案 2 :(得分:4)

无论unsigned int i的价值如何,i >= 0总是如此,因此您的for循环永远不会结束。

换句话说,如果在某个时刻i为0且你递减它,它仍然保持非负数,因为它包含一个巨大的数字,可能是4294967295(即2 32 -1)。

答案 3 :(得分:3)

问题在于:

for (unsigned int i = 9; i >= 0; i--) 

对于unsigned int,您的值为9,退出定义为i&gt; = 0,这将始终为true。 (unsigned int永远不会是负面的!!!)。因此你的循环将重新开始(无限循环,因为i = 0然后-1变为最大值)。

答案 4 :(得分:0)

正如您所说,在循环的最后一步之后发生的无符号数减少到零以下会产生溢出,该数字会环绕到其最大值,因此我们最终会陷入无限循环。

<块引用>

有人可以用无符号整数向我解释反向循环背后的机制吗?

我首选的带有索引的反向循环方法是这样的:

import pandas as pd
inp = [{'a1':'Juancito 1'}, {'a1':'Juancito 2'}, {'a1':'Juancito 3'}]
df = pd.DataFrame(inp)

for i in df['a1']:
    if 'Juancito' in i:
        i = 'Juancito'
    else:
        pass
df.head()

这就是为什么,因为它最接近于等价的普通循环:

for (unsigned int i = 9; i > 0; --i) {
    cout << "i= " << x[i - 1] << endl;
}

然后如果您需要多次访问索引元素并且不想连续写入 [i - 1],则可以在循环的第一行添加类似这样的内容:

for (unsigned int i = 0; i < 9; ++i) {
    cout << "i= " << x[i] << endl;
}