本文主要详细介绍了C迭代器模式中的迭代器,具有一定的参考价值。感兴趣的朋友可以参考一下,希望能帮到你。
:
目录
1.迭代器分类1)正向迭代器2)常量正向迭代器3)反向迭代器4)常量反向迭代器2。迭代器用法示例3。迭代器:它和它哪个更好?(1)前面返回一个引用,后面返回一个对象;(2)临时对象不在前面生成,必须在后面生成,会降低效率;4)迭代器的功能分类;5)迭代器的辅助功能总结。
1.迭代器分类
要访问顺序容器和关联容器中的元素,需要通过迭代器来完成。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的一个元素,它所指向的元素可以通过迭代器读写。从这个角度来看,迭代器类似于指针。
根据定义,迭代器分为以下四种类型。
1) 正向迭代器
定义:容器类名:迭代器迭代器名;
2) 常量正向迭代器
定义:容器类名:const_iterator迭代器名;
3) 反向迭代器
定义:容器类名:reverse_iterator迭代器名;
4) 常量反向迭代器
定义:容器类名:const_reverse_iterator迭代器名;
2.迭代器用法示例
迭代器可以读取它所指向的元素,*迭代器名表示它所指向的元素。非常数迭代器也可以修改它所指向的元素。
迭代器可以操作。反向迭代器和正向迭代器的区别在于:
(1)操作正向迭代器时,迭代器会指向容器中的下一个元素;
(2)反向迭代器操作时,迭代器会指向容器中的前一个元素。
下面的程序演示了如何通过迭代器遍历vector容器中的所有元素。
#包括iostream
#包含矢量
使用命名空间std
int main()
{
向量vec//v是保存int类型变量的变长数组,开头没有元素。
//vector容器有多个构造函数。如果用无参数的构造函数初始化,容器一开始是空的。
for(int n=0;n5;n)
vec . push _ back(n);//push_back成员函数在vector容器的末尾添加一个元素。
vector int:iterator I;//定义正向迭代器
//用迭代器遍历容器
for(I=vec . begin();我!=vec . end();I) {//用迭代器遍历容器
//begin()返回指向容器中第一个元素的迭代器。使得I指向容器中的下一个元素。End()返回的是指向最后一个元素的迭代器而不是指向最后一个元素的迭代器,所以循环的终止条件是I!=v.end()。
cout * I“”;//*i是迭代器I指向的元素。
* I *=2;//每个元素都变成原来的2倍
}
cout endl
//用反向迭代器遍历容器
for(vector int:reverse _ iterator j=vec . Rb egin();j!=vec . rend();j)
//rbegin()返回指向容器中最后一个元素的迭代器,rend()返回指向容器中第一个元素前面位置的迭代器,所以这个循环实际上是从后向前遍历整个数组。
cout * j“”;
返回0;
}
程序的输出结果是:
0 1 2 3 4
8 6 4 2 0
3.迭代器:++it 与 it++ 哪个好?
(1)前置返回一个引用,后置返回一个对象
int运算符(){
* this=1;
返回* this
}
(2)前置不会产生临时对象,后置必须产生临时对象,临时对象会导致效率降低
int运算符(){
int temp=* this//记录修改前的对象
*这个;
返回温度;//返回修改前的对象
}
在第10行和第16行中,编写I,J比编写I,J快。查看作为前后运算符重载的示例,如下所示:
CDemo CDemo:运算符()
{//正面
n;
返回* this
}
CDemo CDemo:运算符(int k)
{//后部
c demo tmp(* this);//记录修改前的对象
n;
返回tmp//返回修改前的对象
}
后生成需要多生成一个本地对象tmp,所以执行速度比前生成慢。同样,迭代器是一个对象。当STL重载迭代器的操作符时,后置形式比后置形式慢。在许多循环中,I和I可能会在运行时间上造成相当大的差异。所以在本教程中,前面提到要养成写I而不是写循环控制变量I的习惯。
注意,容器适配器stack、queue和priority_queue没有迭代器。容器适配器有一些可用于访问元素的成员函数。
4.迭代器的功能分类
不同容器的迭代器有不同的功能。容器迭代器的功能决定了容器是否支持STL中的某种算法。比如排序算法需要通过随机访问迭代器访问容器中的元素,所以有些容器不支持排序算法。
常用的迭代器按功能可分为五种:输入、输出、正向、双向和随机存取。这里只介绍三种常用的迭代器。
1.正向迭代器。假设p是一个前向迭代器,p支持以下操作:p,p,* p .另外,两个前向迭代器可以互相赋值,并且==and!=运算符。
2.双向迭代器。双向迭代器具有正向迭代器的所有功能。此外,如果p是双向迭代器,则p和p都被定义。P使P向与P相反的方向移动。
3.随机访问迭代器。随机迭代器具有双向迭代器的所有功能。如果P是随机访问迭代器,I是整数变量或常数,P也支持以下操作:
P=i:使P向后移动I个元素。
P-=i:使P向前移动I个元素。
p:返回p后第I个元素的迭代器。
P-i:返回p之前第I个元素的迭代器。
P[i]:返回p之后第I个元素的引用。
另外,两个随机访问迭代器p1和p2也可以通过、=、=运算符进行比较。p1p2是指经过几次(至少一次)运算后,P1将等于p2。其他的比较方法也有类似的意思。
对于两个随机访问迭代器p1,p2,也定义了表达式p2-p1,其返回值为p2指向的元素与p1指向的元素的序号之差(或者p2与p1之间的元素个数减一)。
表1显示了不同容器的迭代器的功能。
比如vector的迭代器是随机迭代器,那么遍历vector容器有几种方法。在下面的程序中,每个循环演示一种方法。
[示例]遍历向量容器。
#包括iostream
#包含矢量
使用命名空间std
int main()
{
向量v(100);//v被初始化为有100个元素
for(int I=0;I v . size();I) //size返回元素的个数。
cout v[I];//像普通数组一样使用向量容器
vector int:iterator I;
for(I=v . begin();我!=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;//随机访问迭代器支持'=integer '的运算
}
}
列表容器的迭代器是双向迭代器。假设V和I定义如下:
listint v;
listint:const _ iterator I;
以下代码是合法的:
for(I=v . begin();我!=v . end();我)
cout * I;
以下代码是非法的:
for(I=v . begin();iv . end();我)
cout * I;
因为双向迭代器不支持与“”进行比较。以下代码也是非法的:
for(int I=0;iv . size();我)
cout v[I];
因为list不支持随机访问迭代器的容器,也不支持随机访问其带下标的元素。
在C中,数组也是容器。数组的迭代器是指针,是随机访问迭代器。比如对于数组int a[10],int *类型的指针就是它的迭代器。那么a,a 1,a 2都是a的迭代器。
5.迭代器的辅助函数
STL中有三种操作迭代器的函数模板。它们是:
Advance(p,n):将迭代器p向前或向后移动n个元素。
Distance(p,q):计算两个迭代器之间的距离,即在迭代器P等于迭代器q之前经过了多少次运算,如果调用时P指向q的后面,这个函数就会陷入无限循环。
Iter_swap(p,q):用于交换两个迭代器P,q指向的值。
要使用上述模板,您需要包含头文件算法。下面的程序演示了这三个函数模板的使用。
#包含列表
#包括iostream
#include algorithm //要使用操作迭代器的函数模板,需要包含这个文件。
使用命名空间std
int main()
{
int a[5]={ 1,2,3,4,5 };
list int lst(a,a5);
list int:iterator p=lst . begin();
预付款(第2页);//p向后移动两个元素,指向3
cout ' 1)' * p endl;//输出1)3
前进(p,-1);//p向前移动一个元素,指向2
cout ' 2)' * p endl;//输出2)2
listint:迭代器q=lst . end();
q-;//q指向5
cout '3)'距离(p,q)endl;//输出3)3
iter_swap(p,q);//交换2和5
cout ' 4)';
for(p=lst . begin();p!=lst . end();p)
cout * p“”;
返回0;
}
程序的输出结果是:
3231 5 3 4 2
总结
本文到此为止。希望能帮到你,也希望你能多关注我们的更多内容!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。