首页 > 编程知识 正文

c++迭代器是什么,c++vector用法

时间:2023-05-05 23:52:42 阅读:148810 作者:1453

从http://c.biancheng.net/view/338.html传输。 侵犯删除。

必须在“迭代器”(iterator )中访问序列容器和相关容器中的元素。 迭代器是一个变量,它相当于容器和处理容器的算法之间的中介。 迭代器可以指向容器中的元素,并且可以通过迭代器读写指向的元素。 在这方面,迭代器与指针相似。

迭代器根据定义可分为以下四种。

1 )正迭代器,定义方法如下:

容器类名:迭代器名称;

2 )常数顺序迭代器,定义方法如下:

容器类名:const_iterator迭代器名称;

3 )反向迭代器,定义方法如下。

容器类名:reverse_iterator迭代器名称;

4 )常数迭代器,定义方法如下:

容器类名:3360 const _ reverse _ iterator迭代器名称;

迭代器用法示例迭代器可以读取迭代器指向的元素。 *迭代器名称表示迭代器所指的元素。 通过非常多的迭代器,也可以修改指向的元素。

迭代器可以操作。 反向迭代器和正向迭代器之间的差异如下:

操作前向迭代器时,迭代器指向容器中的下一个元素。 在操作反向迭代器时,迭代器指向容器中的上一个元素。

以下过程说明如何使用迭代器遍历向量容器中的所有元素。

# include iostream # includevectorusingnamespacestd; int main () { vectorint v; //v是存储int型变量的可变长度数组,最初没有要素for (intn=0; n5; n ) v.push_back(n; //push_back成员函数在向量容器的末尾输入元素vector int :迭代器I; //定义正迭代器for (I=v.begin ); I!=v.end (; I ()//迭代器中的容器cout *i ' ); //*i是迭代器I所指的要素*i *=2; //各元素加倍(} cout endl; //使用反向迭代器遍历容器for (vector int :3360 reverse _ iterator j=v.rbegin ); j!=v.rend (; j ) cout *j '; 返回0; }程序的输出结果如下。

0 1 2 3 4

8 6 4 2 0

第六行,矢量容器具有多个构造函数。 用无参数构造函数初始化时,容器最初为空。

第10行,begin成员函数返回指向容器中第一个元素的迭代器。 使I指向容器中的下一个元素。 end成员函数返回指向最后一个元素后面的位置的迭代器,而不是指向最后一个元素的迭代器。 因此,循环的结束条件是I!=v.end (。

第16行定义了用于遍历容器的反向迭代器。 反向操作迭代器时,它将指向容器中的上一个元素。 由于rbegin成员函数返回指向容器中最后一个元素的迭代器,而rend成员函数返回指向容器中第一个元素前面位置的迭代器,因此该循环实际上是从后到前遍历整个数组。

如果迭代器指向容器中最后一个元素之后或第一个元素之前,然后从该迭代器访问该元素,则程序可能会崩溃。 这类似于访问NULL或未初始化的指针所指向的位置。

第10行和第16行,写I、J比写I、J的程序执行速度快。 以下是重载到前置运算符和后置运算符的示例。

CDemo CDemo:operator () )//前置n; return *this; } cdemocdemo :3360操作器(intk ) )//后置cdemotmp ) this ); //记录修正前对象的n; return tmp; //返回修改前的对象)由于后置多生成一个本地对象tmp,因此执行速度比前置慢。 同样,迭代器是一个对象,STL重载迭代器运算符时,后置格式也比前置格式慢。 在次数多的周期中,I和I的执行时间有可能产生很大的差异。 因此,在本教程中,我们提到了对循环控制变量I养成了写I、不写I的习惯。

请注意,容器适配器堆栈、队列和priority_queue没有迭代器。 容器适配器提供了用于访问元素的成员函数。

迭代器的功能分类因集装箱迭代器的不同,其功能强弱也不同。 的迭代器功能的强弱决定了容器是否支持STL的算法。 例如,某些容器可能不是,因为排序算法需要随机访问迭代器以访问容器中的元素

支持排序算法。

常用的迭代器按功能强弱分为输入、输出、正向、双向、随机访问五种,这里只介绍常用的三种。

1) 正向迭代器。假设 p 是一个正向迭代器,则 p 支持以下操作:++p,p++,*p。此外,两个正向迭代器可以互相赋值,还可以用==和!=运算符进行比较。

2) 双向迭代器。双向迭代器具有正向迭代器的全部功能。除此之外,若 p 是一个双向迭代器,则--p和p--都是有定义的。--p使得 p 朝和++p相反的方向移动。

3) 随机访问迭代器。随机访问迭代器具有双向迭代器的全部功能。若 p 是一个随机访问迭代器,i 是一个整型变量或常量,则 p 还支持以下操作:

p+=i:使得 p 往后移动 i 个元素。p-=i:使得 p 往前移动 i 个元素。p+i:返回 p 后面第 i 个元素的迭代器。p-i:返回 p 前面第 i 个元素的迭代器。p[i]:返回 p 后面第 i 个元素的引用。


此外,两个随机访问迭代器 p1、p2 还可以用 <、>、<=、>= 运算符进行比较。p1<p2的含义是:p1 经过若干次(至少一次)++操作后,就会等于 p2。其他比较方式的含义与此类似。

对于两个随机访问迭代器 p1、p2,表达式p2-p1也是有定义的,其返回值是 p2 所指向元素和 p1 所指向元素的序号之差(也可以说是 p2 和 p1 之间的元素个数减一)。

表1所示为不同容器的迭代器的功能。
 

表1:不同容器的迭代器的功能 容器迭代器功能vector随机访问deque随机访问list双向set / multiset双向map / multimap双向stack不支持迭代器queue不支持迭代器priority_queue不支持迭代器


例如,vector 的迭代器是随机迭代器,因此遍历 vector 容器有以下几种做法。下面的程序中,每个循环演示了一种做法。

【实例】遍历 vector 容器。

#include <iostream>#include <vector>using namespace std;int main(){ vector<int> v(100); //v被初始化成有100个元素 for(int i = 0;i < v.size() ; ++i) //size返回元素个数 cout << v[i]; //像普通数组一样使用vector容器 vector<int>::iterator i; for(i = v.begin(); i != v.end (); ++i) //用 != 比较两个迭代器 cout << * i; for(i = v.begin(); i < v.end ();++i) //用 < 比较两个迭代器 cout << * i; i = v.begin(); while(i < v.end()) { //间隔一个输出 cout << * i; i += 2; // 随机访问迭代器支持 "+= 整数" 的操作 }}

list 容器的迭代器是双向迭代器。假设 v 和 i 的定义如下:

list<int> v;list<int>::const_iterator i;

则以下代码是合法的:

for(i=v.begin(); i!=v.end(); ++i)cout << *i;

以下代码则不合法:

for(i=v.begin(); i<v.end(); ++i)cout << *i;

因为双向迭代器不支持用“<”进行比较。以下代码也不合法:

for(int i=0; i<v.size(); ++i)cout << v[i];

因为 list 不支持随机访问迭代器的容器,也不支持用下标随机访问其元素。

在 C++ 中,数组也是容器。数组的迭代器就是指针,而且是随机访问迭代器。例如,对于数组 int a[10],int * 类型的指针就是其迭代器。则 a、a+1、a+2 都是 a 的迭代器。

迭代器的辅助函数

STL 中有用于操作迭代器的三个函数模板,它们是:

advance(p, n):使迭代器 p 向前或向后移动 n 个元素。distance(p, q):计算两个迭代器之间的距离,即迭代器 p 经过多少次 + + 操作后和迭代器 q 相等。如果调用时 p 已经指向 q 的后面,则这个函数会陷入死循环。iter_swap(p, q):用于交换两个迭代器 p、q 指向的值。


要使用上述模板,需要包含头文件 algorithm。下面的程序演示了这三个函数模板的 用法。

#include <list>#include <iostream>#include <algorithm> //要使用操作迭代器的函数模板,需要包含此文件using namespace std;int main(){ int a[5] = { 1, 2, 3, 4, 5 }; list <int> lst(a, a+5); list <int>::iterator p = lst.begin(); advance(p, 2); //p向后移动两个元素,指向3 cout << "1)" << *p << endl; //输出 1)3 advance(p, -1); //p向前移动一个元素,指向2 cout << "2)" << *p << endl; //输出 2)2 list<int>::iterator q = lst.end(); q--; //q 指向 5 cout << "3)" << distance(p, q) << endl; //输出 3)3 iter_swap(p, q); //交换 2 和 5 cout << "4)"; for (p = lst.begin(); p != lst.end(); ++p) cout << *p << " "; return 0;}

程序的输出结果是:
1) 3
2) 2
3) 3
4) 1 5 3 4 2

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。