与许多现代语言不同,普通的C++数组没有 .size()
函数。根据存储类型,你可以选择多种选项来遍历列表。
一些常见的存储选项包括:
std::array<type, size> collection;
std::vector<type> collection;
std::list<type> collection;
int myarray[size];
您的迭代选项将取决于您使用的类型。如果您使用的是普通的C数组,您可以将大小存储在其他地方,或者根据其类型的大小计算数组的大小。通过DevSolar在此答案中概述了计算数组大小的一些缺点。
int oldschool[10];
for(int i = 0; i < 10; ++i) {
oldschool[i];
oldschool[i] = 5;
}
int size = sizeof(oldschool)/sizeof(int);
for(int i = 0; i < size; ++i) {
oldschool[i];
oldschool[i] = 5;
}
如果您使用的任何类型都提供了.begin()
和.end()
函数,那么可以使用它们来获取迭代器,在C++中这被认为是良好的编程风格,相比索引迭代。
std::vector<int> newschool;
for(std::vector<int>::iterator num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num;
*num = 5;
}
for(auto num = newschool.begin(); num != newschool.end(); ++num) {
int current = *num;
*num = 5;
}
std::for_each(newschool.begin(), newschool.end(), function_taking_int);
std::for_each(newschool.begin(), newschool.end(), [](int i) {
});
向量也很特别,因为它们被设计成可以替换数组。您可以使用 .size()
函数来遍历向量,就像遍历数组一样。但是,在C ++中,这被认为是不良实践,您应该尽可能使用迭代器:
std::vector<int> badpractice;
for(int i = 0; i < badpractice.size(); ++i) {
badpractice[i];
badpractice[i] = 5;
}
C++11(新标准)还带来了新的和时髦的基于范围的for循环,它应该适用于任何提供.begin()
和.end()
的类型。然而:编译器对此功能的支持可能会有所不同。您也可以使用begin(type)
和end(type)
作为替代方案。
std::array<int, 10> fancy;
for(int i : fancy) {
}
for(auto num = std::begin(fancy); num != std::end(fancy); ++num) {
int current = *num;
*num = 131;
}
std::begin
还有一个有趣的特性:它可以用于原始数组。这意味着你可以在数组和非数组之间使用相同的迭代语义(但你应该仍然优先选择标准类型而不是原始数组):
int raw[10];
for(auto num = std::begin(raw); num != std::end(raw); ++num) {
int current = *num;
*num = 131;
}
如果您想在循环中从集合中删除项目,那么需要小心,因为调用 container.erase()
会使所有现有的迭代器无效:
std::vector<int> numbers;
for(auto num = numbers.begin(); num != numbers.end(); ) {
...
if(someDeleteCondition) {
num = numbers.erase(num);
} else {
++num;
}
}
这个列表并不全面,但是你可以看到有很多方法来对集合进行迭代。通常情况下,除非有充分的理由,否则最好使用迭代器。