1、不使用引用无法修改数组元素
如果我们想用范围 for 语句修改数组元素,如果不使用引用,则无法修改数组元素。代码示例:
#include <iostream>
using namespace std;
int main()
{
int list[5]= {
1,2,3,4,5 };
for (auto v : list)
v *= 2;
for (auto element : list)
cout << element << " "; // 1 2 3 4 5
return 0;
}
原因解释:
用range-for遍历的时候,遍历的是元素的拷贝。
所以 v 是元素 list[i] 的拷贝,v *= 2 只改变了 v 的值,list[i] 没有改变。因此无法修改数组元素。
用代码形式更直观的演示,for (auto v : list) { v *= 2;} 等价于下面的代码:
// 通过这个代码可以更直观的理解list的元素值是不可能改变的
int list[5] = {
1,2,3,4,5 };
int length = end(list) - begin(list);
for (int i = 0; i != length; i++) {
int v = list[i];
v *= 2;
}
2、使用引用可以修改数组元素
要想修改数组元素,必须使用引用。代码示例:
#include <iostream>
using namespace std;
int main()
{
int list[5] = {
1,2,3,4,5 };
for (auto &v : list)
v *= 2;
for (auto element : list)
cout << element << " "; // 2 4 6 8 10
return 0;
}
原因解释:
定义引用时,程序把引用和它的初始值绑定在一起,而不是将初始值进行拷贝。
改变引用的值,原值也会随之改变。
使用 auto &v : list ,就相当于把 v 作为了 list[i] 的引用。改变 v 的值,list[i] 也随之改变。
3、使用引用的好处
在范围 for 语句中, 使用引用的效率比使用拷贝更高,只是效果不明显。
运行结果的效果相同,只是显示的效果一样,但是程序运行的过程却有很大的差别。代码示例:
for(auto v : list) cout << v << endl;
// 不使用引用的程序执行过程
1. 构造变量int v
2. 给变量v赋值
3. 输出变量v
4. 析构变量v
for(auto &v : list) cout << v << endl;
// 使用引用的程序执行过程
1. 不需要给引用v分配存贮空间,因为引用不是一个对象。
2. 输出变量v
引用是对象的一个别名,使用引用就相当于使用对象本身。既然我可以使用本名,为什么还用多此一举用赋值的方式呢?所以使用引用的效率更高。