饭前小点心
代码
范围for是C++11新引入的写法,适用于任何顺序容器,数组
int main() {
vector<int>a = { 0,1,2,3,4,5 };
for (auto i : a) {
printf("%d ", i);
}
printf("\n");
int b[] = { 6,7,8,9,10 };
for (auto i : b) {
printf("%d ", i);
}
printf("\n");
for (auto& i : b) {
i++;
}
for (auto i : b) {
printf("%d ", i);
}
return 0;
}
输出样例
详解
- 前2个for演示了容器和数组的输出,后面2个演示了修改容器中的值
- 首先,用auto来推断类型,保证了代码的安全性和书写效率
注:auto推断必须给出初始值,此处初始值可以理解为后面容器 - 其次,i作为for循环下的局部遍历,可以被重复定义使用
- 如果要修改容器中的值,必须用引用;
特点总结
- 范围for仅仅只能遍历/修改每一个元素
- 因此范围for不能取得当前元素的地址
- 不能在遍历当前元素时,知道前后元素值
这一点会在很多题上影响 - 更不能对当前容器进行删除等操作
- 因此仅推荐在输出时使用范围for,在处理时用范围for更需要思考的完备性
正餐
或许有人要问了?假如是二维数组怎么办呢!
第一反应
int b[3][4] = { {0,1,2,3},{4,5,6,7},{8,9,10,11} };
for (auto i : b) {
printf("%d ", *i);
}
但是结果是;
这个*也是我测试出来的;
分析结果:表明是二维数组行的首元素;
原理应该是 二维以上的数组 的会自动退化成指针。
修改版
for (auto i : b) {
for(int j=0;j!=4;j++)
printf("%d ", (*i)+j);
}
结果是;
原理是:对地址进行加减,从而输出相同地址上的全部元素
启发:为什么不直接对地址进行遍历呢。因此有了下一个版本
“正式版”
for (auto i : b) {
for (auto j : i) {
printf("%d ", j);
}
}
很抱歉,这个版本无法通过
继续分析原理:原因可能是i作为指针,而j遍历i时会将数组元素转换成指针类型,从而编译出错
因此必须声明i是引用类型
正式版
for (auto& i : b) {//
for (auto j : i) {
printf("%d ", j);
}
}
后记
在用范围for处理多维数组时,除了最内层循环,其他所有循环都用引用;