C++11语法:范围for

基于范围的for循环

1.引入

在 C++98 中如果要遍历一个数组,可以按照以下方式进行:

int arr[] = { 1, 2, 3, 4, 5 };
//方法1:使用下标
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
{
	arr[i] += 2;
}

//方法2:使用指针
for (int* p = arr; p < arr + sizeof(arr) / sizeof(arr[0]); ++p)
{
	*p += 4;
	cout << *p << endl;
}

但是对于一个有范围的集合而言,由程序员来说明for循环的范围是多余的,因为有时候程序员会犯错误,比如边界问题等,因此 C++11标准引入了基于范围的for循环。

注:本文所说的集合指的是数组、标准容器等。

2.说明

for循环中小括号里的内容由冒号“:”分为两部分:

  1. 冒号左边的部分表示范围内用于迭代的变量,该变量在循环迭代期间依次接收集合内不同元素的值。
  2. 冒号右边的部分表示被迭代的范围,也就是有限范围的集合。
int arr[] = { 1, 2, 3, 4, 5 };
//arr内的元素依次拷贝给变量e
for(auto e : arr)  // 即 for(int e : arr)
{
	cout << e << " ";
}
cout << endl;

//我们希望直接改变arr内的元素的值,因此我们给变量e加上引用符号,表示它是元素的别名
for(auto& e : arr)  // 即 for(int& e : arr)
{
	e *= 2;
}

范围内用于迭代的变量(冒号左边的部分)的名称任取,本文统一都用 e 。
我们常常把变量 e 的类型写为 auto,把变量 e 的类型交给编译器去推导。

对集合进行遍历,一般我们会给变量 e 加引用。
因为有些集合元素拷贝给变量 e 时(比如深拷贝),代价较大:拷贝就要开辟空间,一定程度上降低了效率,而加引用表示取别名,可以节省空间,提高效率,比如下面的例子。

struct PersonInfo
{
	string _name;
	string _sex;
	int _age;
	string _tel;
};


int main()
{
	list<PersonInfo> Contact;
	Contact.push_back({ "张三", "男", 21, "1111111111" });
	Contact.push_back({ "李四", "女", 18, "2222222222" });
	Contact.push_back({ "王五", "女", 24, "7777777777" });

	//变量e是Contact元素的别名,这样可以减少拷贝,提高效率
	for (auto& e : Contact)
	{
		cout << e._name << endl;
		cout << e._sex << endl;
		cout << e._age << endl;
		cout << e._tel << endl;
	}

	return 0;
}

使用范围for遍历跟使用普通循环遍历在效果上是等价的,只不过范围for的写法更简洁。与普通循环类似,范围for也可以用 continue 来结束本次循环或用 break 来跳出整个循环。

3.使用条件

  1. for循环迭代的范围必须是确定的。
    对于数组而言,就是第一个元素到最后一个元素的范围;对于类而言,应该提供 begin 和 end 的方法,begin 到 end 就是循环迭代的范围。
  2. 迭代的对象要实现 ++ 和 == 的操作。

4.本质

范围for 实现的本质就是用迭代器进行遍历,只要集合支持迭代器遍历,就能够支持 范围for 。

可将数组的原生指针看为数组的迭代器。

vector<int> v = { 1, 2, 3, 4, 5 };
//使用迭代器进行遍历
auto it = v.begin();
while (it != v.end())
{
	cout << *it << " ";
	++it;
}

//使用范围for进行遍历(实现的本质是迭代器)
for (auto& e : v)
{
	cout << e << " ";
}

这样就能更清楚地理解 范围for 的使用条件了。

【近期文章】
C++11关键字:auto 和 decltype
C++11:列表初始化

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值