C++可以通过遍历数组的索引值,从而获取数组的所有元素:
#include <iostream>
using namespace std;
int main() {
int arr[5] = { 1, 2, 3, 4, 5};
int * p;
for (p = arr; p < arr + sizeof(arr)/sizeof(arr[0]); ++p){
*p *= 2;
}
for (p = arr; p < arr + sizeof(arr)/sizeof(arr[0]); ++p){
cout << *p << '\t';
}
}
除此之外,对于标准模板库中的容器,我们还可以使用for_each模板函数遍历:
#include <algorithm>
#include <iostream>
using namespace std;
int action1(int & e){ e *= 2; }
int action2(int & e){ cout << e << '\t'; }
int main() {
int arr[5] = { 1, 2, 3, 4, 5};
for_each(arr, arr + sizeof(arr)/sizeof(arr[0]), action1);
for_each(arr, arr + sizeof(arr)/sizeof(arr[0]), action2);
}
但是上述两种方式都需要告诉循环体其界限的范围。
而实际上,对于一个有范围的集合来说,由程序员给定范围是多余的,因此C++11引入了基于范围的for,其语法如下:
for(type ele:eles)
{
//do something
}
范围for分为两部分,前者ele为迭代元素(注意不是迭代器,是可以直接访问的元素),后者eles则是被遍历的容器。我们可以基于范围for将前面的例子改为:
#include <iostream>
using namespace std;
int main() {
int arr[5] = { 1, 2, 3, 4, 5 };
for (int & e: arr)
e *= 2;
for (int & e: arr)
cout << e << '\t';
}
这里我们采用的是引用的方式,这是针对需要修改容器元素内容的方式,如果不需要修改则可以不使用引用:
for (int e: arr)
cout << e << '\t';
此外,还可以结合前面说的auto来推导元素类型,使得代码更简洁:
for (auto e: arr)
cout << e << '\t';
当然需要注意auto不会推导引用,需要自己写。
值得指出的是,使用范围for需要一些条件。首先,要求被迭代的对象的范围是可确定的,比如容器累的begin,end,或者是数组的起始位置和结束位置,这些都是用于确定遍历范围。其次,要求迭代对象实现++和==等操作符。
对于正常的stl和内置数组而言,都是符合这些要求的,但是如果用户自己实现,则需要注意实现这些内容。