热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

C++迭代器介绍(iterator、const_iterator、reverse_interator、const_reverse_interator)

这篇文章主要介绍了C++迭代器介绍(iterator、const_iterator、reverse_interator、const_reverse_interator),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

概念: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 v;
const vector v2;
auto it1=v.begin(); //v1是vector::iterator类型
auto it2=v2.cbegin();//v2是vector::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 v;
vector::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 v = {"Hello","fwe",""};
vector::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 <

到此这篇关于C++迭代器介绍(iterator、const_iterator、reverse_interator、const_reverse_interator)的文章就介绍到这了,更多相关C++迭代器内容请搜素以前的文章或下面相关文章,希望大家以后多多支持!


推荐阅读
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Java的集合及其实现类,包括数据结构、抽象类和具体实现类的关系,详细介绍了List接口及其实现类ArrayList的基本操作和特点。文章通过提供相关参考文档和链接,帮助读者更好地理解和使用Java的集合类。 ... [详细]
  • 本文介绍了电流源并联合并的方法,以及谐振电路的原理。谐振电路具有很强的选频能力,通过将电感和电容连接在一起,电流和电压会产生震荡。谐振频率的大小取决于电感和电容的大小,而电路中的电阻会逐渐降低震荡的幅度。电阻和电容组成的电路中,当电容放完电后,电阻两端的电压为0,电流不再流过电容。然而,电感是一种特殊的器件,当有电流流过时,线圈会产生感应磁场,阻止电流的流动,从而使电流不会减小。 ... [详细]
  • 标题: ... [详细]
  • 单点登录原理及实现方案详解
    本文详细介绍了单点登录的原理及实现方案,其中包括共享Session的方式,以及基于Redis的Session共享方案。同时,还分享了作者在应用环境中所遇到的问题和经验,希望对读者有所帮助。 ... [详细]
  • 本文介绍了在Docker容器技术中限制容器对CPU的使用的方法,包括使用-c参数设置容器的内存限额,以及通过设置工作线程数量来充分利用CPU资源。同时,还介绍了容器权重分配的情况,以及如何通过top命令查看容器在CPU资源紧张情况下的使用情况。 ... [详细]
  • 集合的遍历方式及其局限性
    本文介绍了Java中集合的遍历方式,重点介绍了for-each语句的用法和优势。同时指出了for-each语句无法引用数组或集合的索引的局限性。通过示例代码展示了for-each语句的使用方法,并提供了改写为for语句版本的方法。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • position属性absolute与relative的区别和用法详解
    本文详细解读了CSS中的position属性absolute和relative的区别和用法。通过解释绝对定位和相对定位的含义,以及配合TOP、RIGHT、BOTTOM、LEFT进行定位的方式,说明了它们的特性和能够实现的效果。同时指出了在网页居中时使用Absolute可能会出错的原因,即以浏览器左上角为原始点进行定位,不会随着分辨率的变化而变化位置。最后总结了一些使用这两个属性的技巧。 ... [详细]
  • 开发笔记:Docker 上安装启动 MySQL
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Docker上安装启动MySQL相关的知识,希望对你有一定的参考价值。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
author-avatar
mobiledu2502914667
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有