迭代器介绍
用处:指针可以用来遍历存储空间连续的数据结构,但是对于存储空间非连续的,就需要寻找一个行为类似指针的类,来对非数组的数据结构进行遍历。
定义:迭代器是一种检查容器内元素并遍历元素的数据类型,提供了对一个容器中对象的访问方法(每种容器类型都定义了自己的迭代器类型,如
vector:vector< int>:: iterator iter;
),并且定义了容器中对象的范围。
- 迭代器与指针:迭代器(Iterator)是指针(pointer)的泛化,提供了对对象的间接访问。迭代器针对容器,而指针类型针对数组。
- 迭代器与模板:模板使得算法独立于存储的数据类型,即任何数据类型都可以使用该程序设计。而迭代器使得算法独立于使用的容器类型,即任何容器类型都可以使用该通用方法。
每个容器都定义了自己的迭代器,下面例子中即为vector及其迭代器应用(其他容器的迭代器用法见博客:C++:各个容器中迭代器的用法)
#include <iostream>
#include <vector>
using namespace std;
int main()
{
// 创建一个向量存储 int
vector<int> vec;
int i;
// 显示 vec 的原始大小
cout << "vector size = " << vec.size() << endl;
// 推入 5 个值到向量中
for(i = 0; i < 5; i++){
vec.push_back(i);
}
// 显示 vec 扩展后的大小
cout << "extended vector size = " << vec.size() << endl;
// 访问向量中的 5 个值
for(i = 0; i < 5; i++){
cout << "value of vec [" << i << "] = " << vec[i] << endl;
}
// 使用迭代器 iterator 访问值
vector<int>::iterator v = vec.begin();
while( v != vec.end()) {
cout << "value of v = " << *v << endl;
v++;
}
return 0;
}
STL中5种迭代器类型
- Input Iterators(输入):通过对输入迭代器解除引用(类似于指针
*iter
)。最严格的输入迭代只能以只读方式访问对象,且只能读取一次,通常发生在标准输入设备(键盘)读取数据时。例如:istream。注意:只能单步向前,也就是说只可以递增。 - Output Iterators(输出):与 Input Iterators相似,但只是解除引用让程序可以修改容器的值
*iter=value
,不能读取,且只能写入一次,通常发生在向标准输出设备(打印机或屏幕)写入数据时。也属于单步向前迭代器。 - Forward Iterators(正向):可读可写,单步向前。
- Bidirectional Iterators(双向):Forward Iterators+单步向后。
- Random Access Iterators(随机访问):集合上述所有迭代器功能,可以像指针一样进行算术计算。
类型 | 可用操作列表 |
Input :向前遍历,只读,只能读取元素一次 | *iter: 只读访问对应的元素 |
iter->member: 只读访问对应元素的成员 | |
++iter: 向前遍历一步(返回最新的位置) | |
iter++: 向前遍历一步(返回原先的位置) | |
iter1 == iter2: 判断两个迭代器是否相等 | |
iter1 != iter2:判断两个迭代器是否不等 | |
TYPE(iter): 复制迭代器 | |
Output:向前遍历,只写,只能写入元素一次 | *iter = value: 向对应的元素写入新值 |
++iter: 向前遍历一步(返回最新的位置) | |
iter++: 向前遍历一步(返回原先的位置) | |
TYPE(iter): 复制迭代器 | |
Forward :逐个元素向前,可读可写,可访问元素多次 | *iter:; iter->member; ++iter; iter++; iter1 == iter2; iter1 != iter2; TYPE(); TYPE(iter); iter1 = iter2 |
Bidirectional:逐元素向前/向后 | ++iter; iter++; |
Random Access | Bidirectional Iterator所有能力特征 |
iter[n]: 直接访问索引为n的元素 | |
iter+=n: 向前或向后(n为负数)遍历n个元素 | |
iter-=n: 先后或向前(n为负数)遍历n个元素 | |
iter+n(n+iter): 返回当前位置后面第n个元素的iterator位置 | |
iter-n: 返回当前位置前面第n个元素的iterator位置 | |
iter1-iter2: 返回iter1和iter2之间的距离(distance) | |
iter1<iter2: 判断iter1是否在iter2之前 | |
iter1>iter2: 判断iter1是否在iter2之后 | |
iter1<=iter2: 判断iter1是否不再iter2之后 | |
iter1>=iter2: 判断iter1是否不再iter2之前 |
Forward Iterator与Input和Output的区别
- Output Iterator写入数据时,不检查是否已到达结尾;
- Forward Iterator必须保证访问元素的有效性;