迭代器解释(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的区别。

相关推荐

  1. C# 的

    2024-05-14 03:56:09       49 阅读
  2. c++之与反向

    2024-05-14 03:56:09       25 阅读
  3. 模式-C++实现

    2024-05-14 03:56:09       36 阅读
  4. 模式-C#实现

    2024-05-14 03:56:09       30 阅读
  5. C++:的封装思想

    2024-05-14 03:56:09       25 阅读
  6. C++ STL 模块 ——

    2024-05-14 03:56:09       26 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-05-14 03:56:09       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-05-14 03:56:09       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-05-14 03:56:09       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-05-14 03:56:09       18 阅读

热门阅读

  1. getter和setter方法的优缺点

    2024-05-14 03:56:09       12 阅读
  2. leetcode 918.环形子数组的最大和

    2024-05-14 03:56:09       10 阅读
  3. JanusGraph Tinkerpop

    2024-05-14 03:56:09       9 阅读
  4. 船舶检测数据集VOC+YOLO格式7000张6类别

    2024-05-14 03:56:09       11 阅读
  5. 【GoLang基础】panic和recover有什么作用?

    2024-05-14 03:56:09       11 阅读
  6. c++ string容器

    2024-05-14 03:56:09       10 阅读
  7. pat乙1033-旧键盘打字

    2024-05-14 03:56:09       13 阅读
  8. K折交叉验证

    2024-05-14 03:56:09       11 阅读
  9. C++Primer Plus第五章结构编程练习8

    2024-05-14 03:56:09       10 阅读
  10. git开发工作流程

    2024-05-14 03:56:09       12 阅读