五、迭代器--迭代器类型详述

五、迭代器

标签(空格分隔): c++STL


1. 迭代器及其特性

  1. 迭代器本身就是一种对象
  2. 迭代器不是通用指针,而是指向数组的指针概念的抽象
  3. 迭代器就是一个指示器
  4. 迭代器能够使程序反复得对stl容器内容进行访问,当参数化类型为c++内部类型的时候,迭代器是c++的指针。

每种容器都支持某种类别的迭代器,类别有:

  • 输入:为程序需要数据源提供接口,数据源可以是容器,数据流等,输入迭代器只能从一个序列读入数据,此类迭代器可以被修改,引用并进行比较。

  • 输出: 用于输出程序中得到的结果,输出迭代器只能向一个序列输出数据,此类迭代器可以被修改和引用。

  • 前向:可以随意访问序列中的元素,可以用来读,也可写。并能保存迭代器的值,以便重新从原先位置开始遍历。

  • 双向: 能够读写,也可被增值和减值,同时进行前向和逆向操作,所有stl都提供双向迭代器;

  • 随机访问: 可以通过跳跃的方式访问容器中的任意数据,访问数据灵活。具有双向迭代器所有功能,冰球能使用算法和所有迭代器的比较功能。

迭代器的关键属性:
- 当前被指向的元素: 用“*”或“->”表示:
- 指向下一个元素: 迭代器使用增量运算符:++``
- 相等,使用运算符
==`
- 只有随机迭代器可以通过加减整数,取得相对地址;
- 除了输出迭代器之外,可以获得任意两个迭代器的距离(使用distance函数)

2.头文件简述

所有的容器都定义其各自的迭代器,不需要包含专门的头文件。
但是,逆向迭代器包含在头文件<iterator>之中

1. 迭代器类型详述

  1. 迭代器是一种“能够遍历某个序列所有元素”的对象。
  2. 迭代器是抽象概念,只要行为类似迭代器,就是一种迭代器
    迭代器的层次结构为:
    A[Random access]-->B(Bidirectional)
    B-->C[Forward]
    C-->D[input]
    C-->E[Output]

Input迭代器:用于向前读取
Output迭代器: 用于向前写入
Forward迭代器: 用于读取和写入;
Bidirectional迭代器: 双向迭代器用于前后读取写入;
Random access 迭代器: 随机存取 ,用于读取写入

1.输入型迭代器(InputIterator)

  1. 只能一次次地向前读取元素,并按照顺序传回元素值。
  2. 迭代器只能读取元素一次
  3. 如果两个输入型迭代器占用一个位置,则两者相同

输入型迭代器的操作:

  • * :从迭代器中读取元素值
  • -> :读取元素的成员
  • ++: 代表前向步进;最好使用前置递增,性能更好
  • ==: 判断相等
  • !=: 判断不等
  • TYPE(iter) : 赋值迭代器

2. 输出型迭代器(OutputIterator)

  1. 作用是将元素逐个写入。即只能逐个元素赋值。
  2. 不能使用输出型迭代器同一个序列进行两次遍历
  3. 输出型可以实现的操作有: *,++和复制操作

例子:
1. “将元素写至标准输出装置”的迭代器,如果采用两个输出型迭代器,第二个字将跟在第一个字的后面,而不是覆盖;

  1. “插入器(inserter)”

3. 前向迭代器

前向迭代器是输入型和输出型迭代器的组合。
前向迭代器的操作;

表达式效果
*Iter取实际元素
Iter->number存取实际元素的成员
++Iter向前步进
Iter++向前步进
Iter == Iter2判断两个迭代器相等
Iter1 != Iter2判断两个迭代器不等
TYPE()产生迭代器(默认构造函数)
TYPE(Iter)复制迭代器
Iter1=Iter2赋值

前向迭代器能多次指向同一集合的同一元素,并能多次处理同一元素;
- Output迭代器: 无需检查是否抵达尾端,可直接写入数据。不提供比较操作,不能讲Output迭代器和尾端迭代器比较。
- Forward迭代器: 在使用之前,需要确保迭代器是否有效! 在使用的时候,尽量使用begin()和end()作为循环的起始。

4.双向迭代器

双向迭代器在前向迭代器的基础上增加了回头遍历的功能。可以支持递减运算符。
新增操作:

表达式效果
–Iter / Iter–步退

5.随机存取迭代器

在双向迭代器的基础上增加了随机存取能力。
因此,必须增加迭代器运算操作。即可以实现迭代器加减某个偏移量,能处理距离问题,并可运用<>等关系运算符操作。
可以支持随机存取迭代器的容器对象或数据类型有:
- vector
- deque
- strings(string,wstring)两个string类型
- array 普通数组

随机迭代器的各项操作

表达式效果
Iter[n]存取索引位置为n的元素
Iter+=n前进n个元素
Iter-=n后退n 个元素
Iter+n / n+Iter传回iter之后的第n个元素
Iter-n传回iter之前的第n个元素
Iter1 - Iter2判断Iter1和Iter2的距离
Iter1 < Iter2判断iter1是否在iter2之前
Iter1 > Iter2判断iter1 是否在iter2 之后
Iter1 <= Iter2判断iter1是否不在iter2之后
Iter1 >= Iter2判断iter1是否不再iter2之前

【注: 】随机存取迭代器对 listsets还有maps是无效的。

6.vector迭代器的递增和递减

一般可以递增或递减暂时性容器,但是对弈vector和string容器不同;
如:

vector<int> v;
if(v.size() >1) {
sort(++v.begin(),v.end());
}

上述代码在编译的时候会出错,换成deque,就能通过编译。
原因:
1. vector 迭代器在实际操作中通常作为一般指针。c++不允许修改任何基本类型的暂时值;对于struct和class则可以;
2. 如果迭代器被实例化一般指针,编译会失败;如果迭代器被实例化class,则编译成功。deque,lists,sets和maps总能通过编译,因为这些容器的迭代器不可能被实例化为一般指针;

本内容摘抄自《c++标准程序库开发指南–不要重复造轮子》第二版
实验了一下,我在vs2013编译通过,没有出现这个问题,记录一下:不懂其中的原理。

//vs 2013
vector<int> vec2 = {9,3,3,5,2,3,1,6,7};
if (vec2.size() >1) {
    sort(++vec2.begin(), vec2.end());
}
--------------省略----------------

结果为;

size: 9
vec2: 9   1   2   3   3   3   5   6   7
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值