前言
迭代器可以算是c++编程中比较高级的的内容了,如果你对此还一无所知,可能你需要先了解一下模板,容器的概念。说到迭代器,首先这个名字就给人一种很厉害的感觉,他是个什么东东呢?迭代器扮演容器与算法之间的胶合剂,是所谓的“泛型指针”。而指针是c语言中就有的东西,迭代器是c++中才有的,指针用起来灵活高效,迭代器功能更丰富些。本文由代码引例逐步进入迭代器的学习。
迭代器介绍
一段关于迭代器的定义和使用的简单程序。
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> ivec;
ivec.push_back(1);
ivec.push_back(2);
ivec.push_back(3);
ivec.push_back(4);
for(vector<int>::iterator iter = ivec.begin();iter != ivec.end(); ++iter)
cout << *iter << endl;
return 0;
}
每种容器都定义了一对名为begin和end的函数,其中begin成员返回指向第一个元素(第一个字符)的迭代器,而end成员返回指向容器尾元素的下一个位置的迭代器,也就是说end指示的是一个不存在的元素,所以叫end返回的是尾后迭代器。一般我们清楚一个迭代器的准确类型是什么,所以我们都是使用auto或者decltype来定义变量的。如果vector为空,则begin返回的迭代器和end返回的迭代器相同。一旦向上面这样定义和初始化,就相当于把该迭代器和容器进行了某种关联,就像把一个指针初始化为指向某一空间地址一样。
迭代器的种类
种类及支持的操作
种类 | 支持操作 |
---|---|
输入迭代器 | 是只读迭代器,在每个被遍历的位置上只能读取一次。 |
输出迭代器 | 是只写迭代器,在每个被遍历的位置上只能被写一次。 |
前向迭代器 | 兼具输入和输出迭代器的能力,但是它可以对同一个位置重复进行读和写。但它不支持operator–,所以只能向前移动。 |
双向迭代器 | 很像前向迭代器,只是它向后移动和向前移动同样容易。 |
随机访问迭代器 | 有双向迭代器的所有功能。而且,它还提供了“迭代器算术”,即在一步内可以向前或向后跳跃任意位置, 包含指针的所有操作,可进行随机访问,随意移动指定的步数。支持前面四种Iterator的所有操作,并另外支持it + n、it - n、it += n、 it -= n、it1 - it2和it[n]等操作。 |
下面是一个关于
输入迭代器的示例
,find函数参数就是输入迭代器。
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
int arr[5] = { 1, 2, 3, 5, 6};
vector<int> iVec(arr, arr + 5);//定义容器vector
list<int> iList(arr, arr + 5);//定义容器list
//在容器iVec的头部和尾部之间寻找整形数3
vector<int>::iterator iter1 = find(iVec.begin(), iVec.end(), 3);
if (iter1 == iVec.end())
cout<<"3 not found"<<endl;
else
cout<<"3 found"<<endl;
//在容器iList的头部和尾部之间寻找整形数4
list<int>::iterator iter2 = find(iList.begin(), iList.end(), 4);
if (iter2 == iList.end())
cout<<"4 not found"<<endl;
else
cout<<"4 found"<<endl;
return 0;
}
find函数是这样的
template<typename InputIterator, typename T>
InputIterator find(InputIterator first, InputIterator last, const T &value)
{
while (first != last && *frist != value)
++first;
return first;
}
基本操作
迭代器的一些常用操作
*iter //对iter进行解引用,返回迭代器iter指向的元素的引用
iter->men //对iter进行解引用,获取指定元素中名为men的成员。等效于(*iter).men
++iter //给iter加1,使其指向容器的下一个元素
iter++
--iter //给iter减1,使其指向容器的前一个元素
iter--
iter1==iter2 //比较两个迭代器是否相等,当它们指向同一个容器的同一个元素或者都指向同同一个容器的超出末端的下一个位置时,它们相等
iter1!=iter2
运算操作
iter+n //在迭代器上加(减)整数n,将产生指向容器中钱前面(后面)第n个元素的迭代器。新计算出来的迭代器必须指向容器中的元素或超出容器末端的下一个元素
iter-n
iter1+=iter2 //将iter1加上或减去iter2的运算结果赋给iter1。两个迭代器必须指向容器中的元素或超出容器末端的下一个元素
iter1-=iter2
iter1-iter2 //两个迭代器的减法,得出两个迭代器的距离。两个迭代器必须指向容器中的元素或超出容器末端的下一个元素
>,>=,<,<= //元素靠后的迭代器大于靠前的迭代器。两个迭代器必须指向容器中的元素或超出容器末端的下一个元素
迭代器的const_iterator
每种容器还定义了一种名为const_iterator的类型。该类型的迭代器只能读取容器中的元素,不能用于改变其值。之前的例子中,普通的迭代器可以对容器中的元素进行解引用并修改,而const_iterator类型的迭代器只能用于读不能进行重写。例如可以进行如下操作:
for(vector<int>::const_iterator iter=ivec.begin();iter!=ivec.end();++iter)
cout<<*iter<<endl; //合法,读取容器中元素值
for(vector<int>::const_iterator iter=ivec.begin();iter!=ivec.end();++iter)
*iter=0; //不合法,不能进行写操作
const_iterator和const iterator是不一样的,后者对迭代器进行声明时,必须对迭代器进行初始化,并且一旦初始化后就不能修改其值。这有点像常量指针和指针常量的关系。例如:
vector<int> ivec(10);
const vector<int>::iterator iter=ivec.begin();
*iter=0; //合法,可以改变其指向的元素的值
++iter; //不合法,无法改变其指向的位置
其他<简单>示例代码
如果你是初次学习迭代器很可能有些懵,附上一些很简单的demo便于理解迭代器和容器中各种数据结构的相关内容(下载地址:https://download.youkuaiyun.com/download/shylonegirl/10708782)。如果你已经比较熟悉了迭代器和容器,那么这些对你没有任何帮助。
参考
除各种已无法详细溯源的编程著作外还参考了这些互联网资源,感谢他们的分享。
https://www.cnblogs.com/hdk1993/p/4419779.html
https://www.cnblogs.com/maluning/p/8570717.html
https://www.cnblogs.com/wxquare/p/4699429.html
https://blog.youkuaiyun.com/qq_35644234/article/details/52331948