概念:C++的一种机制,用来遍历标准模板库容器中的元素,是一种"智能"指针
一、迭代器的特点
- 迭代器是一种智能指针,具有遍历复杂数据结构的能力
- 不同的容器有不一样的内部结构,因此会有一样的迭代器类型
- 迭代器定义后,并不属于某一实例容器对象,只要是属于该迭代器类型的容器类型都可用
迭代器的分类
C++的STL定义了5种迭代器
- 输入迭代器:提供了对其指向元素的只读操作以及前++和后++操作符
- 输出迭代器:提供了对其指向元素的写操作和++操作符
- 向前迭代器:具有++操作符
- 双向迭代器:既具有++操作符也具有--操作符
- 随机访问迭代器:是一般的迭代器,既可以随机的实现跳跃跳动,也可以通过指针算术运算来实现跳跃移动
二、迭代器的使用
1.原理:迭代器定义之后,可指向指定类型容器内的元素,从而达到访问容器内元素的能力
2.用法
- 关键字interator代表声明一个迭代器,前面需要指明类型
- 迭代器指向容器的某一位置
- 通过*解引用获取元素的引用(注:*得到的是元素的引用)。也可用->得到该元素的成员(下面代码会介绍)
string s= "HelloWorld"; string::iterator i; //一个string类型的迭代器 for (i = s.begin(); i != s.end(); i++) { cout << *i; }
3.解引用和成员访问
注意:访问成员时,要对迭代器加上(),否则产生的意义不同
(*item).empty(); //正确用法 *item.empty; //错误用法
上面代码中:第一行是解引用迭代器。而第二种是试图访问item中的empty成员,但是item是个迭代器,显示是错误的
三、interator、const_iterator
1.迭代器的核心关键字
属于容器的内部成员,通过作用域限定符::访问
2.分类
- interator:当我们需要对容器元素进行修改、删除等操作时或者对象是非常量时使用
- const_iterator:当我们只是遍历容器元素,而不更改容器元素时或者对象是常量时使用
注意:上面所说的常量是指常量容器,而不是容器内的元素为常量
3.两者的选择
建议:如果我们只是简单的遍历容器元素或者对象是常量时,一般使用const_iterator比较合适
4.C++11标准:cbegin()、cend()
C++11引进了两个新函数,分别为cbegin()、cend(),其两者的功能类似于begin()、end()
C++11标准之前,iterator与const_iterator都使用begin()、end()两个辅助函数遍历容器。
C++11标准之后,const_iterator既可以使用可以使用begin()、end(),也可以使用cbegin()、cend()。但是iterator还是只能使用begin()、end()
vector<int> v; const vector<int> v2; auto it1=v.begin(); //v1是vector<int>::iterator类型 auto it2=v2.cbegin();//v2是vector<int>::const_iterator类型
四、reverse_interator、const_reverse_interator
1.概念
标准模板库容器的逆序迭代器
功能与interator、const_iterator均相同,但是用法不一样
2.两者区别
- reverse_interator:与interator相同,改变容器内部元素时使用。只能使用rbegin()、rend()
- const_reverse_interator:与const_iterator相同,只是单纯遍历容器内部元素时使用。能使用rbegin()、rend()、crbegin()、crend()
3.用法
用法的原理与interator、const_iterator是相同的
但是rbegin()、rend()分别指向容器元素的最后一个位置与第一个元素的前一个位置
//for循环打印的是3、2、1 vector<int> v; vector<int>::const_reverse_iterator iter; v.push_back(1); v.push_back(2); v.push_back(3); for (iter = v.rbegin(); iter != v.rend(); iter++) printf("%d\t", *iter);
五、begin()、end()、cbegin()、cend()
4者都是容器的成员函数
cbegin()与cend()与begin()和end()原理相同,下面只介绍begin()与end()
1.概念:begin()、end()代表容器的特殊位置,分别为元素的第一个位置与最后一个元素的下一个位置
下面比如是vector的一个模型,则begin()、end()分别代表一下位置
2.为什么要这样设计?
- begin():我们在遍历容器的元素的时候,一般要获取该元素的首元素,因此设计bengin()
- end():当我们用迭代器遍历容器的时候,一般需要结束条件(如遍历到最后一个元素),但是遍历到最后一个元素时又不能舍弃它,因此将最后一个元素的下一位置作为结束标志
六、rbegin()、rend()、crbegin()、crend()
这四者的原理与begin()、end()、cbegin()、cend()是相同的,也都是容器的成员函数
但是rbegin()、rend()分别代表最后一个元素与第一个元素的前一个位置
七、迭代器的运算
说明:迭代器的运算符一般都是对迭代器所指元素的位置进行比较,返回的是比较结果或者改变迭代器的位置
迭代器没有+运算
例如有迭代器iter,iter1,iter2
*iter 返回迭代器所指元素的引用
iter->data 代表当前所指位置处元素的的指针,可以访问其函数或成员,等价于(*iter).data
++iter 令迭代器指向容器的下一个元素
--iter 令迭代器指向容器的前一个元素
iter1==iter2 判断两个迭代器的位置是否相同
iter1!=iter2 同上
>、>=、<、<= 同上
iter + n 改变迭代器的位置
iter - n 同上
iter +=n 同上
iter -=n 同上
iter1 - iter2 两个迭代器相减,返回它们之间的距离
实例:遍历vector中的元素,如果遇到空白,停止遍历
vector<string> v = {"Hello","fwe",""}; vector<string>::iterator iter; for (iter = v.begin(); iter != v.end() && !iter->empty(); ++iter) { cout << *iter<<"\t"; }
八、一些代码事例
将string中的第一个字符改为大写
string s = "helloWorld"; string::iterator it; if (s.begin() != s.end())//先判断s不为空 { it = s.begin(); *it = toupper(*it); }
使用容器元素的函数
(*item).empty(); //判断是否为空 (*item).size(); //得到大小
得到中间元素的迭代器
auto mid=v.begin()+vi.size()/2;
折半查找string中的一个元素
string s = "abcdefghj"; char foundChar = 'e'; string::const_iterator l_iter=s.begin(); string::const_iterator r_iter=s.end(); string::const_iterator mid_iter = s.begin() + (r_iter - l_iter) / 2; while (mid_iter != r_iter && *mid_iter != foundChar) { if (*mid_iter > foundChar) { r_iter = mid_iter; } else { l_iter = mid_iter + 1; } mid_iter = l_iter + (r_iter - l_iter) / 2; } cout << *mid_iter << endl;
到此这篇关于C++迭代器介绍(iterator、const_iterator、reverse_interator、const_reverse_interator)的文章就介绍到这了,更多相关C++迭代器内容请搜素自由互联以前的文章或下面相关文章,希望大家以后多多支持自由互联!