在c++中迭代一个向量的正确方法是什么?

考虑这两个代码片段,这一个工作得很好:

for (unsigned i=0; i < polygon.size(); i++) {
    sum += polygon[i];
}

还有这个:

for (int i=0; i < polygon.size(); i++) {
    sum += polygon[i];
}

生成警告:有符号整数表达式和无符号整数表达式之间的比较。

对我来说,无符号变量看起来有点吓人,我知道无符号变量如果使用不当会很危险,所以-这是正确的吗?


当前回答

考虑是否需要迭代

<algorithm>标准标头为我们提供了这样的工具:

using std::begin;  // allows argument-dependent lookup even
using std::end;    // if the container type is unknown here
auto sum = std::accumulate(begin(polygon), end(polygon), 0);

算法库中的其他函数执行常见任务——如果您想节省精力,请确保您知道哪些函数可用。

其他回答

讲一点历史:

为了表示一个数字是否为负,计算机使用“符号”位。Int是一种有符号的数据类型,这意味着它可以保存正数和负数(大约- 20亿到20亿)。Unsigned只能存储正数(因为它不浪费元数据,所以可以存储更多:0到40亿)。

Std::vector::size()返回一个无符号值,因为向量的长度怎么可能是负的呢?

警告告诉您,不等式语句的右操作数可以比左操作数保存更多的数据。

从本质上讲,如果你有一个超过20亿项的向量,你使用一个整数来索引,你会遇到溢出问题(int将返回到- 20亿)。

for (vector<int>::iterator it = polygon.begin(); it != polygon.end(); it++)
    sum += *it; 

在您示例中的特定情况下,我将使用STL算法来实现这一点。

#include <numeric> 

sum = std::accumulate( polygon.begin(), polygon.end(), 0 );

对于更一般,但仍然相当简单的情况,我认为:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

using namespace boost::lambda;
std::for_each( polygon.begin(), polygon.end(), sum += _1 );

考虑是否需要迭代

<algorithm>标准标头为我们提供了这样的工具:

using std::begin;  // allows argument-dependent lookup even
using std::end;    // if the container type is unknown here
auto sum = std::accumulate(begin(polygon), end(polygon), 0);

算法库中的其他函数执行常见任务——如果您想节省精力,请确保您知道哪些函数可用。

这两个代码段的工作原理相同。然而,unsigned int"路由是正确的。使用unsigned int类型将更好地用于使用它的实例中的vector。在vector对象上调用size()成员函数将返回一个无符号整数值,因此您希望将变量“i”与其自身类型的值进行比较。

此外,如果你仍然对“unsigned int”在代码中的表现感到不安,可以试试“uint”。这基本上是“unsigned int”的缩写版本,它的工作原理完全相同。您也不需要包含其他头文件来使用它。