迭代器解释(C++)

一、什么是迭代器

为了提高C++编程的效率,STL(Standard Template Library)中提供了许多容器,包括vector、list、map、set等。然而有些容器(vector)可以通过下标索引的方式访问容器里面的数据,但是大部分的容器(list、map、set)不能使用这种方式访问容器中的元素。为了统一访问不同容器时的访问方式,STL为每种容器在实现的时候设计了一个内嵌的iterator类,不同的容器有自己专属的迭代器(专属迭代器负责实现对应容器访问元素的具体细节),使用迭代器来访问容器中的数据。除此之外,通过迭代器可以将容器和通用算法结合在一起,只要给予算法不同的迭代器,就可以对不同容器执行相同的操作,例如find查找函数(因为迭代器提供了统一的访问方式,这是使用迭代器带来的好处)。迭代器对一些基本操作如*、->、++、==、!=、=进行了重载,使其具有了遍历复杂数据结构的能力,其遍历机制取决于所遍历的容器,所有迭代器的使用和指针的使用非常相似。通过begin,end函数获取容器的头部和尾部迭代器,end迭代器不包含在容器之内,当begin和end返回的迭代器相同时表示容器为空。

STL主要由 容器、迭代器、算法、函数对象、和内存分配器 五大部分构成。

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> v;
	//初始化容器
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}
	//利用迭代器遍历容器
	for (vector<int>::iterator it = v.begin(); it != v.end(); ++it)
	{
		cout << *it << " ";
	}
}

二、迭代器类型

按照迭代器的功能强弱,可以把迭代器分为以下几种类型:

1、输入迭代器

功能:

  • 通用的四种功能
  • 只能利用迭代器进行输入功能
  • 它只能用于单遍扫描算法

2、输出迭代器

功能:

  • 通用的四种功能
  • 只能利用迭代器进行输入功能
  • 只能用于单遍扫描算法

3、前向迭代器

功能:

  • 通用的四种功能
  • 能利用迭代器进行输入和输出功能
  • 能用于多遍扫描算法

4、双向迭代器

功能:

  • 通用的四种功能
  • 能利用迭代器进行输入和输出功能
  • 能用于多遍扫描算法
  • 前置和后置递减运算(- -),这意味这它能够双向访问

随机访问迭代器

功能:

  • 通用的四种功能
  • 能利用迭代器进行输入和输出功能
  • 前置和后置递减运算(- -)(意味着它是双向移动的)
  • 比较两个迭代器相对位置的关系运算符(<、<=、>、>=)
  • 支持和一个整数值的加减运算(+、+=、-、-=)
  • 两个迭代器上的减法运算符(-),得到两个迭代器的距离
  • 支持下标运算符(iter[n]),访问距离起始迭代器n个距离的迭代器指向的元素
  • 能用于多遍扫描算法。 在支持双向移动的基础上,支持前后位置的比较、随机存取、直接移动n个距离

三、常用容器的迭代器

vector ——随机访问迭代器

deque——随机访问迭代器

list —— 双向迭代器

set / multiset——双向迭代器

map / multimap——双向迭代器

stack——不支持迭代器

queue——不支持迭代器

四、实例

双向迭代器随机访问迭代器是最为常用的,因此下面演示这两种迭代器的用法

双向迭代器

#include <iostream>
#include <list>
using namespace std;

int main()
{
	list<int> lst;
	for (int i = 0; i < 10; ++i)
	{
		lst.push_back(i);
	}
	list<int>::iterator it;//创建list的迭代器
	cout << "遍历lst并打印: ";
	for (it = lst.begin(); it != lst.end(); ++it)//用 != 比较两个迭代器
	{
		cout << *it << " ";
	}
	//此时it=lst.end(),这个位置是最后一个元素的下一个位置,没有存储数据
	--it;//等价于it--,回到上一个位置
	//it -= 1; //报错,虽然都是-1,但这种方式是随机迭代器才有的功能
	cout << "\nlst的最后一个元素为:" << *it << endl;
}

随机访问迭代器

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> v;
	for (int i = 0; i < 10; ++i)
	{
		v.push_back(i);
	}
	vector<int>::iterator it;
	for (it = v.begin(); it != v.end(); ++it) //用 != 比较两个迭代器
	{
		cout << *it << " ";
	}
	cout << endl;
	for (it = v.begin(); it < v.end(); ++it) //用 < 比较两个迭代器
	{
		cout << *it << " ";
	}
	cout << endl;
	it = v.begin();//让迭代器重新指向首个元素的位置
	while (it < v.end())//间隔一个输出
	{
		cout << *it << " ";
		it += 2; // 用 += 移动迭代器
	}
	cout << endl;

	it = v.begin();
	cout << it[5] << endl; //用[]访问
}

对于vector容器来说,其迭代器有失效的可能。
vector容器有动态扩容的功能,每当容器容量不足时,vector就会进行动态扩容,动态扩容不是在原来的空间后面追加空间,而是在寻找一段新的更大的空间,把原来的元素复制过去。
但是这样一来,容器存储元素的位置就改变了,原来的迭代器还是指向原来的位置,因此每次进行动态扩容后原来的迭代器就会失效。

这里可以查看之前发过的vector和list的区别。

  • 29
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值