C++ stl之迭代器(iterator)

C++ STL六大组件-4-Iterator(迭代器) 视C++为一个语言联邦: 理解C++的全貌,学习C++的编程范式:过程/面向对象/函数式/元编程/泛型编程。 尽量以const/enum/inline替换#define:对于单纯的常量,最好用const对象/enums来替换#define,对于形似函数的宏,最好用inline函数替换#define. 尽可能使用const:const可以用于任何作用域内的对象/函数参数/函数返回类型/成员函数本体。可以帮助避免出错。 确定对象被使用前已经先被初始化:读取未初始化的值会导致不明确的行为。 了解C++ . 阅读详情

经过前面对各容器的讲解,相信大家已经对迭代器有一定的了解了,迭代器作为STL中的几大模块之一(系统工具,容器,迭代器,算法,仿函数,string以及iostream),重要性毋庸置疑,现在我们来详细的讨论分析STL中迭代器的用法。

迭代器产生动机:

在早期STL 的实现中,容器和算法是合并在一起的,即每个容器都有他的专属算法,但是后来发现这样效率不高,而且每个容器的很多算法都是大致相同的,于是STL的设计者萌生了把算法和容器分开的想法,即算法只写一次,每个容器都可以调用。从而需要在容器和算法之间需要一个中间变量充当桥梁,由此,迭代器应运而生了。

 

 

请注意,上面的图表关系并不代表继承关系,只是下面是上面的扩充集

(因为STL中的迭代器现在只用最后两种,前三种只做简单介绍)

Input_iterator (输入迭代器):输入迭代器只能向前一步一步向前读取元素,而且一个位置只能读一次。

Output_iterator(输出迭代器):输出迭代器只能用来向前一步一步写入元素,一个位置只能写入一次。

Forward_iterator(前向迭代器):前向迭代器基本能做输入输出迭代器可以做的一切事情,既可以读取,也可以写入,而且还可以多次,但是没变的是也只能一步一步的向前,不可跨越。

Bidirectional iterators(双向迭代器):双向迭代器在前向迭代器的基础上做了修改,增加了后退的操作,所以叫双向,同时也保存了前向迭代器的一切特性,但是也只能一步一步的操作,不可跨越,支持他的容器有List set multiset map multimap 。

注意:双向迭代器本身只能支持++ —— !=  == 操作,不能如下这样使用:

List<int> coll;

List<int>::iterator it;

For(it=coll.begin();it<coll.end();it+1)     //error

```````````````````````````````````````

第一个错误在于it<coll.end();双向迭代器不支持<操作符。

第二个错误在于 it+1;双向迭代器只能it++。

所以必须这样写:

For(it=coll.begin();it!=coll.end();it++) 

其实也不能想像,在list是由链表实现的,链表访问任何一个位置的元素都只能从表头依次读取下去,不能直接访问那个元素,其他几个容器类似。

Random access iterators(随机存取迭代器):

随机存取迭代器在双向迭代器的基础上在增加了随机存取的能力,他可以增加某个偏移量或减去某偏移量,能处理距离的问题并运用< >运算符,也可以像数组一样随机的访问或者修改某个元素,是现在迭代器的最高进化版本。如果把上面那个错误例子的list改为vector,那就正确。随机存取迭代器跟一般的指针支持的运算一致。他支持的容器是vector deque..

迭代器几个相关辅助函数:

1:advance() 可令迭代器前进或者后退指定的位。

template<class InIt, class Dist>

void advance(InIt& it, Dist n);

第一个参数是传入迭代器,第二个参数一般是整数,如果为正,则表示前进n位,反之则后退n位。(注意在迭代器中往后走代表前进,往前走代表后退)

 

 

2:distance() 可以处理两个迭代器之间的位置。

template<class Init, class Dist>

    ptrdiff_t distance(InIt first, InIt last);

该函数传入两个迭代器,返回他们相隔的距离,但是务必保证两个迭代器一定要是同一个容器上的,否则导致未定义行为。

3:iter_swap 可以交换两个迭代器所指的的值(迭代器位置不变)

template<class FwdIt1, class FwdIt2>

void iter_swap(FwdIt1 x, FwdIt2 y);

两个参数为两个迭代器,执行完后所指的值被交换。

相信到这里,大家也许会疑惑,随机存储迭代器可以直接相减求距离,也可以直接相加,也可直接交换,那为什么还要这几个函数,其实这几个函数主要是为非随机存取迭代器服务的,因为他们本身不具有这些功能,当他们用于随机存取迭代器,执行的跟我们自己操作的一样,具有常数复杂度,用于双向迭代器的具有对数复杂度。

下面我们针对前面所讲的举一个简单的例子:

#include<iostream>

#include<vector>

#include<list>

#include<algorithm>

using namespace std;

int main()

{

vector<int> vec;

list<int> lis;

for(int by=1;by<21;++by)

{

vec.push_back(by);

lis.push_back(by);

}

vector<int>::iterator it1,it2;

list<int>::iterator io1,io2;

cout<<"对于distance()的用法:"<<endl;

it1=find(vec.begin(),vec.end(),3);

io1=find(lis.begin(),lis.end(),3);

it2=find(vec.begin(),vec.end(),13);

io2=find(lis.begin(),lis.end(),13); 

cout<<"vector中的相距位置:"<<(it2-it1)<<endl;

cout<<"list中的相距位置:"<<distance(io1,io2)<<endl<<endl;

cout<<"对于advance()的用法:"<<endl;

cout<<"vector中的相距位置:"<<(it2+3)-(it1+2)<<endl;

advance(io1,2);

advance(io2,3);

cout<<"list中的相距位置:"<<distance(io1,io2)<<endl<<endl;

cout<<"对于iter_swap()的用法:"<<endl;

cout<<"在vector中利用中间变量交换"<<endl;

int mid;

mid=*(it1+2);

*(it1+2)=*(it2+3);

*(it2+3)=mid;

copy(vec.begin(),vec.end(),ostream_iterator<int>(cout," "));

cout<<endl;

cout<<"在list中利用iter_swap()交换:"<<endl;

iter_swap(io1,io2);

copy(lis.begin(),lis.end(),ostream_iterator<int>(cout," "));

cout<<endl;

  system("pause");

return 0;

}

 

 

对于这个例子,其实就是分别存储1到20的数字在两个不同类型的容器中(当然这里主要是指他们的不同迭代器)。然后分别找到3和13的迭代器位置,vector中可以直接相减得出距离,list只能用distance函数,分别偏移相同的单位,在算出距离。最后交换迭代器所指的内容,很明显16和5的位置改变了。

这个小程序很简单,但是他所体现出来的两种迭代器的不同点却是显然的,一般迭代器辅助函数我们都只对双向迭代器使用,因为随机存取迭代器没必要,但是也要看实际情况而定!讲到这里,主要问题就是理解随机存取迭代器和双向迭代器的区别,关于他们更多的区别,在算法中还会提到。

 

 

 

 

 

 

移远EC800M CAT1模块HTTP POST实战:从AT指令到数据上报的完整避坑指南 本文详细介绍了移远EC800M CAT1模块通过AT指令实现HTTP POST数据上报的完整开发流程,包括模块初始化、PDP上下文配置、HTTP POST实现及优化策略。针对实际开发中的常见问题如网络异常、低功耗需求等提供了经过验证的解决方案,帮助开发者快速实现稳定可靠的物联网数据传输功能。 阅读详情

相关推荐

学习记录——SIMPACK生成轨道谱文件的方法

生成轨道谱文件的方法,可以用于实测轨道谱导入和自制轨道谱导入仿真

weixin_51965897的博客 7795

C++ STL中iterator迭代器移动操作

文章目录iterator迭代器简介:迭代器的操作:1. begin(): 该函数用于返回容器的开始位置2. end():该函数用于返回容器的后结束位置3. advance( ) 将迭代器往前或往后移动 n 个元素位置4. next:移动n位置后返回一个新迭代器5 . prev:移动n位置后,返回n的前一个迭代器6. inserter:在容器中的任意位置插入元素7. fill_n:在n开始的范围插入指定数量的值迭代器的类型:输入迭代器输出迭代器前向迭代器双向迭代器随机访问迭代器 iterator迭代器简介:

a15322910600的博客 4769

STM32嵌入式开发实战:如何用miniLZO压缩算法节省70%存储空间(附完整工程)

本文详细介绍了如何在STM32嵌入式开发中使用miniLZO无损压缩算法实现高达70%的存储空间节省。通过对比分析不同轻量级算法,重点讲解miniLZO的内存优化配置、分块压缩策略和完整工程实现,帮助开发者有效解决嵌入式系统中的存储瓶颈问题。

ss78901的博客 881

Java迭代器(转)(iterator详解以及和for循环的区别)

迭代器是一种模式,它可以使得对于序列类型的数据结构的遍历行为与被遍历的对象分离,即我们无需关心该序列的底层结构是什么样子的。只要拿到这个对象,使用迭代器就可以遍历这个对象的内部. 1.Iterator Java提供一个专门的迭代器>Iterator,我们可以对某个序列实现该interface,来提供标准的Java迭代器。Iterator接口实现后的功能是“使用”一个迭代器. 文档定义:

zxq1138634642的专栏 6万+

数字后端流程--place

Floorplan完成后芯片的大致框架已经出现,万里长征已经迈出特别重要的第一步了,前面的步骤我们已经完成了io port,macro的摆放,现在core外只剩下std cell(标准单元)了,Place这一步就是要把std cell放进core里。看到密密麻麻的std cell也不用紧张,因为放std cell不用像macro手动一个一个摆,工具就可以帮我们完成大部分工作。虽然这一步的工作只有一个,但也不是只要Place完就能进行下一步的,衡量Place质量是否满足标准会通过以下几点判断。

qq_68400574的博客 771

ANSYS Twin Builder实战:5步搞定数字孪生模型部署(附ROM配置技巧)

本文详细解析了ANSYS Twin Builder在数字孪生模型部署中的实战应用,重点介绍了ROM(降阶模型)配置技巧。通过5个关键步骤,从环境搭建到工业部署,帮助工程师高效实现高精度三维仿真到轻量化数字孪生的转化,提升预测性维护和系统仿真效率。

weixin_27330481的博客 655

[C++]迭代器iterator的实现(支持编译器for块简易写法)

什么是迭代器? 以下是维基百科的简介. 迭代器(iterator),是确使用户可在容器对象(container,例如链表或数组)上遍访的对象[1][2][3],设计人员使用此接口无需关心容器对象的内存分配的实现细节。其行为很像数据库技术中的光标(cursor),迭代器最早出现在1974年设计的CLU编程语言中。 在各种语言实现迭代器的方式皆不尽同,有些面向对象语言像Java、C#、Ruby、Python、Delphi都已将迭代器的特性内置语言当中,完美的跟语言集成,我们称之隐式迭代器。但像是C++语言本身

八宝咸鱼 1725

AI测试入门:如何测试AI对话模型/智能体?「详细介绍」

作为测试人员,我们需要掌握特定的技能和方法来有效地测试这些复杂的AI对话模型和智能体。传统的软件测试方法在这里可能不再完全适用,我们需要开发新的测试策略和技术来应对AI系统的独特特性。在这篇文章中,我们将深入探讨如何测试AI对话模型和智能体。

blues_C的博客 6855

Iterator迭代器

java迭代器Iterator讲解

程序员阿龙的博客 3454

【BIM入门实战】Revit创建地形的几种方法及优缺点

Revit在体量和场地选项卡的【地形表面】工具可以创建三维地形,有三种方法:放置点、指定点文件和导入实例文件、倾斜摄影点云技术和InfraWorks地形生成。 文章目录1. 放置点2. 指定点文件3. 导入实例文件4. 倾斜摄影点云技术5. InfraWorks地形生成 1. 放置点 放置点功能位于体量和场地选项卡下地形表面,点开找到放置点,并通过自定义设置点的高程值来创建地形的高程数据。 优点:通过用户自定义高程点来绘制模型,使地形更为精确。 缺点:只适用于面积小的项目,面积太大,人工效率低下。 .

智慧空间实验室 4757

kylinos-SP3的软件包降级到V10-SP1中的版本

如果想再次回退到原来版本,将repo改为原来的SP3版本,然后执行yum history 查看ID号,执行yum history rollback ID就可以恢复了。此时我们发现已安装的版本是1.32-2.ky10,而sp1网络源里的版本是1.30-11.ky10,我们将降级安装网络源中的低版本软件包。近期有个客户想要把kylinos-V10-sp3的软件包降级到kylinos-V10-SP1的版本。3、以tar包为例,查看已安装版本及网络源中其他版本。1、查看系统版本,确认是V10-SP3。

太极淘的博客 1103

迭代器(iterator)看这篇就够了

迭代器很重要,是遍历线性数据结构(链表)的重要方法之一。迭代器仅仅是遍历输出语句!本身并没有任何排序等其他功能,在数据结构的二叉树中别认为迭代器输出二叉树是因为迭代器会排序,是因为排序二叉树本身有序,迭代器仅仅是按照排序二叉树本身的排序规则输出罢了。

若葉的博客 10万+

【AI编程】Trae 环境搭建与配置从使用到项目实战详解

Trae 环境搭建与配置从使用到项目实战详解

congge 5650

C++ STL const_iterator转换为iterator类型迭代器(深入了解,一文学会)

在 advance() 和 distance() 函数各自的功能和用法基础上,继续讲解如何利用这 2 个函数实现将 const_iterator 迭代器转换为 iterator 迭代器,或者将 const_reverse_iterator 迭代器转换为 reverse_iterator 迭代器。 注意,上面提到的 iterator、const_iterator、reverse_iterator 和 const_reverse_iterator 是 C++ STL 标准库提供了 4 种基础迭...

断点 1943

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

C++ STL stream_iterator流迭代器(深入了解,一文学会)

流迭代器也是一种迭代器适配器,不过和之前讲的迭代器适配器有所差别,它的操作对象不再是某个容器,而是流对象。即通过流迭代器,我们可以读取指定流对象中的数据,也可以将数据写入到流对象中。 介于流对象又可细分为输入流对象(istream)和输出流对象(ostream),C++ STL 标准库中,也对应的提供了 2 类流迭代器: 将绑定到输入流对象的迭代器称为输入流迭代器(istream_iterator),其可以用来读取输入流中的数据; 将绑定到输出流对象的迭代器称为输出流迭...

断点 3634

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

C++ STL:迭代器特性 iterator_traits

STL的算法需要知道iterator的相关信息(iterator种类、iterator指向的元素的类型...),来决定使用最优化的算法。然而,原生指针本身并不是一个类类型,它们没有定义,但是标准库中泛型算法和容器希望迭代器都有上面提到的5种特性,但是对于原生指针,并没有任何结构定义。支持前面四种Iterator的所有操作,并另外支持it + n、it - n、it += n、 it -= n、it1 - it2和it[n]等操作。不同类型的迭代器支持的操作不同,在算法优化的时候需要用到。

_ 1361

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C++ STL 迭代器iterator设计

迭代器是一种抽象的设计概念,现实设计语言中并没有直接对应于这个概念的实物。iterator模式定义:提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该聚合物的内部表达方式。

surfaceyan的博客 721

迭代器修改元素_C++ STL六大组件4Iterator(迭代器)

C++ STL 迭代器STL概述的一个重要特点是数据结构和算法的分离。尽管这是个简单的概念,但这种分离确实使得算法变得非常通用。例如,由于函数是完全通用的,你可以用它来操作几乎任何数据集合,包括链表,容器和数组。在C++ STL 中,对容器中数据的读和写,是通过迭代器完成的,扮演着容器和算法之间的胶合剂。只要容器提供迭代器的接口,同一套算法代码可以利用在完全不同的容器中,这是抽象思想的经...

weixin_39880337的博客 1246

C++ STL insert_iterator插入迭代器适配器(深入了解,一文学会)

插入迭代器适配器(insert_iterator),简称插入迭代器或者插入器,其功能就是向指定容器中插入元素。值得一提的是,根据插入位置的不同,C++ STL 标准库提供了 3 种插入迭代器: 迭代器适配器 功能 back_insert_iterator 在指定容器的尾部插入新元素,但前提必须是提供有 push_back() 成员方法的容器(包括vector、deque 和 list)。 front_insert_iterator 在指定容器的头部插入新元素,但...

断点 2930

C++STL insert_iterator(插入迭代器)、ostream迭代器的重载

今天看侯老的STL源码剖析看到insert_iterator这一块突然发现一个细节 上图用inserter适配器来当copy函数的第三参数,我们知道copy的第三参数需要是一个迭代器,那么我们很自然的能够想到inserter应该是返回的一个insert_iterator类型的对象。 如图,确实是这样的,返回的是一个insert_iterator类型临时对象。 然后我们看图上copy的源码,发现对...

苞米地里捉小鸡的博客 664

C++迭代器(STL迭代器)iterator详解

转自http://c.biancheng.net/view/338.html。侵删。 要访问顺序容器和关联容器中的元素,需要通过“迭代器(iterator)”进行。迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。迭代器可以指向容器中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。 迭代器按照定义方式分成以下四种。 1) 正向迭代器,定义方法如下: 容器类名...

又帅又酷的红头发10号 1万+

从零开始学C++之STL(十):迭代器适配器{(插入迭代器back_insert_iterator)、IO流迭代器(istream_iterator、ostream_iterator)}

一、迭代器适配器 反向迭代器 插入迭代器 IO流迭代器 其中反向迭代器可以参考以前的文章。 二、插入迭代器 插入迭代器实际上是一个输出迭代器(*it=; ++) back_insert_iterator back_inserter front_insert_iterator front_inserter 先来看示例:

Meditation 3552

C++ STL Iterator 迭代器

TOCTOC。

gopher9511的博客 935

C++ STL Custom Iterator 自定义迭代器

【代码】C++ STL 自定义迭代器(create a custom iterator)

GPU全栈博主 939

C++ STL 迭代器 iterator

几乎所有标准库容器都定义了各自的 iterator 类型,所有当使用特定容器的时候,不需要包含特殊的 iterator 头文件。不过一些特殊的 iterator,例如 reverse iterator,以及若干个辅助函数被定义于 头文件 <iterator> 中。

2401_83484142的博客 1205
上一篇: STL容器之deque
下一篇: 迭代器适配器(iterator adapters)
lloil
博客等级 码龄14年 382粉丝 50原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值