C++中用于循环的无符号整数

Unsigned integers in C++ for loops

本文关键字:无符号整数 循环 用于 C++      更新时间:2023-10-16

我对Stackoverflow进行了一些研究,研究C++中使用无符号整数而不是有符号整数的循环的反向。但我仍然不明白为什么会出现问题(请参阅for循环的无符号int反向迭代)。为什么下面的代码会产生分段错误?

#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会等于零,因为存在类似溢出的情况。但我认为无符号整数可以取零值,不是吗?现在,如果我用一个有符号的整数替换它,那绝对没有问题。

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

非常感谢!

这里的问题是无符号整数从不为负数。

因此,环路测试:

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--)

问题是,您的循环允许i低至零,并且只有当i小于0时才期望退出循环。由于i是无符号的,所以它永远不能小于0。它滚动到2^32-1。这大于向量的大小,因此会导致segfault。

无论unsigned int i的值是多少,i >= 0总是正确的,因此for循环永远不会结束。

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

问题就在这里:

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

您从一个无符号int的值9开始,您的出口定义是i>=0,这将始终为真。(无符号int永远不会为负数!!)。正因为如此,你的循环将重新开始(无休止的循环,因为i=0,然后-1变为最大uint)。

正如您所说,在循环的最后一步之后,一个无符号的值降到零以下,会产生溢出,这个数字会达到其最大值,因此我们最终会产生一个无限循环。

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

我对带索引的反向循环的首选方法是:

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

这就是为什么,因为它最接近于正常环路的等价物:

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

如果你需要多次访问索引元素,并且不想连续写入[i-1],你可以添加这样的内容作为循环中的第一行:

auto& my_element = my_vector[i - 1];