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

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

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

还有这个:

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

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

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


当前回答

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

其他回答

第一个是类型正确,严格意义上的正确。(如果你想的是,size永远不可能小于零。)不过,这个警告在我看来是一个很好的被忽视的警告。

使用size_t:

for (size_t i=0; i < polygon.size(); i++)

引用维基百科:

stdlib.h和stddef.h头文件定义了一种名为size_t的数据类型,用于表示对象的大小。接受大小的标准库函数期望它们是size_t类型,而sizeof操作符的计算结果为size_t。 size_t的实际类型取决于平台;一个常见的错误是假定size_t与unsigned int相同,这可能导致编程错误,特别是在64位体系结构变得越来越普遍的情况下。

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

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

四年过去了,谷歌给了我这个答案。在标准c++ 11(又名c++ 0x)中,实际上有一种新的令人愉快的方式来做到这一点(以打破向后兼容性为代价):新的auto关键字。它为您省去了必须显式指定要使用的迭代器类型(再次重复vector类型)的痛苦,而(对编译器来说)显然应该使用哪种类型。v是你的向量,你可以这样做:

for ( auto i = v.begin(); i != v.end(); i++ ) {
    std::cout << *i << std::endl;
}

c++ 11甚至更进一步,提供了一种特殊的语法,用于迭代向量等集合。它消除了写千篇一律的东西的必要性:

for ( auto &i : v ) {
    std::cout << i << std::endl;
}

要在工作程序中查看它,构建一个auto.cpp文件:

#include <vector>
#include <iostream>

int main(void) {
    std::vector<int> v = std::vector<int>();
    v.push_back(17);
    v.push_back(12);
    v.push_back(23);
    v.push_back(42);
    for ( auto &i : v ) {
        std::cout << i << std::endl;
    }
    return 0;
}

在写这篇文章时,当你用g++编译它时,你通常需要通过给出一个额外的标志来设置它与新标准一起工作:

g++ -std=c++0x -o auto auto.cpp

现在你可以运行这个例子:

$ ./auto
17
12
23
42

请注意,关于编译和运行的说明是特定于Linux上的gnu c++编译器的,程序应该是平台(和编译器)独立的。

考虑是否需要迭代

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

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