关于C++范围for循环的探讨
在C#,Python,Java等高级语言相继引入范围for循环功能后,C++11在C++98/03标准之后,引入范围for循环。
C++98:for循环
for(表达式 1; 表达式 2; 表达式 3){
//循环体
}
在C++98以及03之前,C++中的范围for循环采用上述的结构,自由度和灵活度都大打折扣。
char arc[] = "hello,Li Huan Ying!!!";
int i;
//for循环遍历普通数组
for (i = 0; i < strlen(arc); i++) {
cout << arc[i];
}
cout << endl;
当时的另一种处理方法是使用迭代器遍历。
vector<char>myvector(arc,arc+10);
vector<char>::iterator iter;
//for循环遍历 vector 容器
for (iter = myvector.begin(); iter != myvector.end(); ++iter) {
cout << *iter;
}
C++11:for循环
C++11增加了全新的增强for循环使用方法。语法结构如下:
for (declaration : expression){
//循环体
}
其中,两个参数各自的含义如下:
- declaration:表示此处要定义一个变量,该变量的类型为要遍历序列中存储元素的类型。需要注意的是,C++ 11 标准中,declaration参数处定义的变量类型可以用 auto 关键字表示,该关键字可以使编译器自行推导该变量的数据类型。
- expression:表示要遍历的序列,常见的可以为事先定义好的普通数组或者容器,还可以是用 {} 大括号初始化的序列。
char arc[] = "hello,Li Huan Ying!!!";
int i;
//for循环遍历普通数组
for (auto Ser:arc) {
cout <<Ser <<" ";
}
cout << endl;
注意:Ser在此处并非迭代器类型。而是,表示arc中的每个元素。
同时,新的语法支持使用大括号进行进行范围for循环遍历。
for (int num : {1, 2, 3, 4, 5}) {
cout << num << " ";
}
也可以直接在原地进行修改
for (int num : {1, 2, 3, 4, 5}) {
cout << num++ << " ";
}
在上述的遍历中,需要明确的一点是,遍历时无论该序列是普通数组、容器还是用{ }大括号包裹的初始化列表,遍历序列的变量都表示的是当前序列中的各个元素。即,它们并非以迭代器的形式在遍历。
for (char ch : "hello,Li Huan Ying!!!") {
cout << ch;
}
总结:基于范围的 for 循环可以遍历普通数组、string字符串、容器以及初始化列表。for 循环冒号后还可以放置返回 string 字符串以及容器对象的函数。
如下:
arc = "hello,Li Huan Ying!!!";
string retStr() {
return str;
}
for(char ch:retStr())
cout<<ch<<" ";
值得一提的是函数只在第一次进行调用。
上面虽然说过遍历时并非使用迭代器,而是单个元素,但是遍历的底层实现任然是借助于迭代器进行的。可以做这样的测试:
std::vector<int>arr = { 1, 2, 3, 4, 5 };
for (auto val : arr)
{
std::cout << val << std::endl;
arr.push_back(10); //向容器中添加元素
}
我们可以看到输出的结果出错啦。即是因为容器元素的迭代器出现了错误。失效啦。
另外,出于性能的考量,可以使用引用来遍历,而非传值的复制方法。
const char Arc[] = "hello, Li Huan ying!!!";
for(auto& cha:Arc)
cout<<cha<<" ";
加上const限定词,也可以防止修改:
vector<int> Test {1,2,5,6,21,6,12,465654,6,2,1,4,15};
for (const int num : retVector())
cout<<num<<" ";
//cout<<num++<<" "; //报错
好的,结束。欢迎讨论。