C++中用于循环的无符号整数
Unsigned integers in C++ for loops
我对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];
- 如何打印boost多精度128位无符号整数
- C++模板函数,用于比较任何无符号整数和有符号整数
- 在线程中读取无符号整数时,c++ 位是否以原子方式切换?
- Constexpr 可变参数模板,用于对无符号整数进行重新排序
- 为什么 Clang 和 GCC 中两个无符号整数之和的结果类型不同
- 从 std::string 转换为 const 无符号整数
- 迭代器和无符号整数的重载 + 运算符
- C++,概念不适用于无符号整数作为结果类型?
- 在C++中,将无符号整数转换为八进制表示,反之亦然的最佳方法是什么
- 原子式清除无符号整数的最低非零位
- 计算机使用什么方法添加无符号整数
- boost::任何带有结构体和无符号整数
- 添加有符号和无符号整数
- 如何安全地比较两个无符号整数计数器?
- 计算 (64 位无符号整数) * (64 位无符号整数) 的商除以 2^64
- 如何将 32 位无符号整数分配给包含 32 位的位字段
- 如何将以"\0"开头的字符 * 转换为无符号整数?
- 而无符号整数条件的循环
- C++中用于循环的无符号整数
- 我的For循环出了什么问题?我得到警告:有符号和无符号整数表达式之间的比较[-Wsigncompare]