一、范围for的基本语法
在C++98中如果要遍历一个数组,可以按照以下方式进行:
#include<iostream> using namespace std; void TestFor() { int array[] = { 1, 2, 3, 4, 5 }; for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i) cout << array[i] << " "; cout << endl; } int main() { TestFor(); return 0; }
对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。
for循环后的括号由冒号“ :”分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围。
看范围 for 语句的定义:
for (declaration : expression)
statement
其中,expression部分是个序列,declaration部分负责定义一个变量,该变量将被用于访问序列中的基础元素。
代码实例
#include<iostream> using namespace std; void TestFor2() { int array[] = { 1, 2, 3, 4, 5 }; //定义一个变量 e 然后每次都从array取数据赋值给e,自动判断结束 for (auto e : array) e *= 2; for (auto e : array) cout << e << " "; } int main() { TestFor2(); return 0; }
注意:与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。
二、范围for中使用引用 (一些奇葩的问题)
看了上面的代码我们如果想利用范围for去改变数组中的值那我们应该怎么办呢?其实很好办我们只需要范围for里面的变量改成引用类型就行了。
例如:
#include<iostream> using namespace std; void TestFor3() { int array[] = { 1, 2, 3, 4, 5 }; //定义一个变量 e 然后每次都从array取数据赋值给e,自动判断结束 for (auto& e : array) { e *= 2; cout << e << " "; } } int main() { TestFor3(); return 0; }
看到这里如果你细心的话就会想:“这里面引用变量 e 怎么能够改变绑定呢?”实际上,范围for中的变量 e是每次迭代,e变量会被重新创建,所以这里的引用相当于不断地被初始化。
当然同样在for()循环中还有一个例子与这里变量 e 的创建方式相同,还有一个例子与这里变量 e 的创建方式不同,
①相同
#include<iostream> using namespace std; int main() { int i = 0; for (i = 0; i < 10; i++) { int a = 10; cout << a << " "; a++; } return 0; }
这是因为a是局部变量,每次重新循环,a都会重新创建,和上面的范围for中使用引用类似。
②不同
在for()循环的初始化列表中创建的变量不会每次重新循环时会重新创建,但是for()循环结束时,在for()循环的初始化列表中创建的变量也会消失。
#include<iostream> using namespace std; int main() { for (int i = 0; i < 10; i++) { cout << i << " "; } return 0; }
讨论
范围for中的变量的创建与上面正常for()循环的第一种方式相像,可能它们的实现方式一样,这个我不太了解,如果有明白的小伙伴可以评论区一起讨论一下。
三、范围for的使用条件
- for循环迭代的范围必须是确定的
对于数组而言,就是数组中第一个元素和最后一个元素的范围; 对于类而言,应该提供begin和end的方法,begin和end就是for循环迭代的范围。
注意:以下代码就有问题,因为函数传参不会传数组,数组名代表首元素的地址,因此for的范围无法确定。
void TestFor(int array[]) { for(auto& e : array) cout<< e <<endl; }





