C++STL的迭代器(iterator)

一、定义

        迭代器是一种检查容器内元素并且遍历容器内元素的数据类型

        【引用自:C++迭代器(iterator)_c++ iterator_NiUoW的博客-CSDN博客】迭代器是一个变量,相当于容器和操纵容器的算法之间的中介。C++更趋向于使用迭代器而不是数组下标操作,因为标准库为每一种标准容器(如vector、map和list等)定义了一种迭代器类型,而只有少数容器(如vector)支持数组下标操作访问容器元素。可以通过迭代器指向你想访问容器的元素地址,通过*x打印出元素值。这和我们所熟知的指针极其类似。

        C语言有指针,指针用起来十分灵活高效。C++语言有迭代器,迭代器相对于指针而言功能更为丰富。

        vector,是数组实现的,也就是说,只要知道数组的首地址,就能访问到后面的元素。所以,我们可以通过访问vector的迭代器来遍历vector容器元素。
        List,是链表实现的,我们知道,链表的元素都存储在一段不是连续的地址空间中。我们需要通过next指针来访问下一个元素。那么,我们也可以通过访问list的迭代器来实现遍历list容器元素。

        由此可见,迭代器和容器是密不可分的、紧密相连的的关系。不同的容器,它们的迭代器也是不同的,但是它们的迭代器功能是一样的。假如没有迭代器,由于vector和list容器的存储特点,你需要两种算法去实现遍历vector和list容器的功能,复杂且低效。有了迭代器,遍历容器的效率会大大提高。

二、为什么要使用迭代器

         使用STL(Standard Template Library)中的迭代器有以下几个好处:

1. 统一的访问方式:STL的迭代器提供了一种统一的访问容器元素的方式,无论是数组、链表、集合还是映射,都可以通过相同的迭代器接口进行遍历和访问。这种统一性简化了代码的书写,并提高了代码的可读性和可维护性。

2. 安全的访问操作:迭代器在设计上考虑了容器的边界情况,确保不会越界访问或访问非法内存引起崩溃。迭代器提供了递增、递减等操作符,使得在容器中前进或后退一个位置变得简单和安全。

3. 灵活的遍历方式:迭代器支持正向遍历、反向遍历以及跳跃式遍历等方式,使得在不同的情况下选择合适的遍历方式变得方便。比如,可以使用反向迭代器从容器的末尾向前遍历,或者使用跳跃式迭代器按照一定规则跳过一些元素。

4. 可算法化处理:STL提供了丰富的算法,如排序、查找、拷贝、删除等,这些算法可以直接操作迭代器,而不需要关心具体容器的实现。使用迭代器作为算法的参数,使得代码可复用性更强,可以将同一套算法应用于不同类型的容器。

5. 可组合的操作:迭代器的操作是可以组合的,可以在不同的操作之间进行链式调用,形成更复杂的操作序列。这种可组合性使得代码更加灵活,可以根据需求自由组合和定制迭代器操作,实现更多样化的功能。

        总之,STL中的迭代器提供了一种抽象的、统一的访问容器元素的方式,使得我们可以以一种通用的方式处理各种不同类型的容器。这样做可以提高代码的重用性、可读性和可维护性,同时还能够充分利用STL提供的丰富算法,简化开发过程并提高效率。

另一种解释:【取自C++STL之迭代器(iterator)详解_c++迭代器-CSDN博客】

(1) STL提供每种容器的实现原理各不相同,如果没有迭代器我们需要记住每一种容器中对象的访问方法,很显然这样会变得非常麻烦。

(2) 每个容器中都实现了一个迭代器用于对容器中对象的访问,虽然每个容器中的迭代器的实现方式不一样,但是对于用户来说操作方法是一致的,也就说通过迭代器统一了对所有容器的访问方式。

(3) 迭代器的使用可以提高编程的效率。

三、迭代器的使用

3.1 基本使用方法

(1) 首先要定义一个迭代器类型变量(这里以vector容器为例)。
定义方法如下:容器类名::iterator 迭代器名;
如要定义vector容器的迭代器:vector<int>::iterator iter;(这里的iter是变量名,可以自定义)
(2) 接下来要利用迭代器访问容器数据
先要了解几个成员函数,如下表所示。

成员函数功能
begin()返回指向容器中第一个元素的正向迭代器;如果是 const 类型容器,在该函数返回的是常量正向选代器。
end()返回指向容器最后一个元素之后一个位置的正向迭代器,如果是 onst 类型容器,在该函数返回的是常量正向迭代器。此函数通常和 begin() 搭配使用。
rbegin()返回指向最后一个元素的反向迭代器,如果是 const 类型容器,在该函数返回的是常量反向迭代器。
rend()返回指向第一个元素之前一个位置的反向迭代器。如果是 const 类型容器,在该函数返回的是常量反向迭代器。此函数通常和 begin() 搭配使甲。

这里的 end()、rend() 函数要注意,不是指向容器最后一个元素,而是后一个位置(看图) 

 (3) 示例

#include<iostream>
#include<vector>int main() {std::vector <int> vec; // 定义向量对象vecvec.push_back(2);vec.push_back(3);vec.push_back(5);vec.push_back(9);// 至此,向量vec中包含四个元素,分别是2,3,5,9std::vector<int>::iterator iter; // 定义迭代器类型变量iteriter = vec.begin(); // 变量被赋值为指向第一个元素的迭代器std::cout << *iter << std::endl;iter++; // 可以用自增操作,让iter指向下一个元素std::cout << *iter << std::endl;iter = vec.begin() + 2; // 让iter指向容器中的第三个位置std::cout << *iter << std::endl;
}

输出结果:
2 3 5  

注意:vector容器迭代器属于随机访问迭代器,可以一次移动多个位置,如iter=v1.begin()+2;
也可以用iter=iter+2;

3.2 容器数据的遍历

3.2.1 常见方法(正序遍历)

for (auto it = container.begin(); it != container.end(); ++it) {// process element *it
}

3.2.2 常见方法(逆序遍历) 

for (auto it = container.rbegin(); it != container.rend(); ++it) {// process element *it
}

        其中,auto是C++11的关键字,它可以自动推导迭代器类型。循环中,首先使用begin()函数获取容器起始位置的迭代器,然后每次使用递增运算符前进一个位置,直到迭代器等于end()函数返回的迭代器时结束循环。

3.2.3 注意问题 

        需要注意的是,在处理空容器或只有一个元素的容器时,begin()end()函数返回的迭代器是相同的,因此在循环中不能使用!=运算符进行比较,而应该使用    或   运算符判断是否越界。

        当一个容器为空或只有一个元素时,`begin()`和`end()`函数返回的迭代器是同一个位置,因此使用`!=`运算符进行比较可能会得到错误的结果。

        对于空容器,`begin()`和`end()`函数都返回指向末尾的迭代器,因为没有元素可以遍历。这种情况下,应该直接判断迭代器是否等于末尾迭代器,如下所示:

std::vector<int> v;
if (v.begin() == v.end()) {// 处理空容器的情况
}

        对于只有一个元素的容器,`begin()`和`end()`函数虽然会返回不同的迭代器,但是它们指向的是同一个位置,即容器中唯一的元素。这种情况下,应该使用`<`或`>`运算符进行比较,如下所示:

std::vector<int> v{1};
for (auto it = v.begin(); it < v.end(); ++it) { // 注意这里使用<std::cout << *it << std::endl;
}

        同样地,在循环中也可以使用`>=`或`<=`运算符判断是否越界,但是更好的做法是使用标准库提供的迭代器判等函数`std::equal()`、`std::lexicographical_compare()`等,这些函数会自动处理空容器和只有一个元素的容器的情况,并提供更好的可读性和代码健壮性。

3.2.4 遍历应用示例

#include<iostream>
#include<vector>int main() {std::vector <int> vec; // 定义向量对象vecvec.push_back(2);vec.push_back(3);vec.push_back(5);vec.push_back(9);// 至此,向量vec中包含四个元素,分别是2,3,5,9// 遍历向量vec中的所有元素for (auto iter = vec.begin(); iter != vec.end(); iter++) {std::cout << *iter << " ";}std:: cout << std::endl;
}

注意:上面说到end()函数是指向容器的最后一个元素的后一个位置,所以当迭代器指向最后的后一个位置时结束遍历,便可以访问所有容器元素。  

输出结果:

2 3 5 9 

四、不同容器的迭代器(iterator)的功能

vector                  随机访问
deque                  随机访问
list                        双向
set / multiset        双向
map / multimap    双向
stack                    不支持迭代器
queue                  不支持迭代器
priority_queue     不支持迭代器
 

参考文献

C++STL之迭代器(iterator)详解_c++迭代器-CSDN博客
C++迭代器(iterator)_c++ iterator_NiUoW的博客-CSDN博客
关于迭代器失效的几种情况-CSDN博客(值得阅读)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/166991.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day01_matplotlib_demo

文章目录 折线图plot多个绘图区绘制数学函数图像散点图scatter柱状图bar直方图histogram饼图pie总结 折线图plot import matplotlib.pyplot as pltplt.figure(figsize(15, 6), dpi80) plt.plot([1, 0, 9], [4, 5, 6]) plt.show()### 展现一周天气温度情况 # 创建画布 plt.figu…

【C++】引用’‘的深入解析

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

C语言学习系列->动态内存管理

文章目录 前言概述&#x1f6a9;malloc and free&#x1f51c;malloc&#x1f51c;free &#x1f6a9;calloc and realloc&#x1f51c;calloc&#x1f51c;realloc 前言 要想学好数据结构&#xff0c;在C语言学习过程中就需要把指针、结构体和动态内存管理学好。在前面的文章&…

makesense在线yolov5标注

文章目录 一、创建图片文件夹和label.txt二、在线标注数据 参考文章博主&#xff1a;风吹落叶花飘荡 一、创建图片文件夹和label.txt 创建一个放置图片的文件夹images&#xff0c;存放需要标注的图片&#xff08;图片最好重命名为1,2,3…避免后面混淆&#xff09; 创建label.t…

C++标准模板(STL)- 类型支持 (运行时类型识别,type_info )

运行时类型识别 定义于头文件 <typeinfo> 含有某个类型的信息&#xff0c;由实现生成。​​这是 typeid 运算符所返回的类。 std::type_info 定义于头文件 <typeinfo> class type_info; 类 type_info 保有一个类型的实现指定信息&#xff0c;包括类型的名称和…

我单方面宣布:腾讯云服务器优惠价格(双11特价)

2023腾讯云双十一服务器优惠价格表多少钱一年&#xff1f;轻量服务器2核2G3M、2核2G4M、2核4G5M、4核8G12M、8核16G18M、16核32G28M和云服务器CVM标准型S5实例优惠价格&#xff0c;腾讯云百科今年双11服务器价格会在当前的价格基础上享受个9折优惠&#xff0c;可领券 https://c…

正则表达式之学习笔记

正则表达式学习笔记 一、概念二、正则表达式组成三、常见的正则表达式3.1 .匹配任意字符3.2 * 匹配前一个字符的0个或多个实例3.3 ^ 匹配输入字符串的开头3.4 $ 匹配行尾3.5 [] 匹配字符集合\<\> 精确匹配符号 一、概念 正则表达式是由一系列特殊字符组成的字符串&#…

Linux---(三)基本指令大全

前提引入&#xff1a;历史上先出现的键盘还是鼠标&#xff1f; 答案&#xff1a;键盘 ✨所以刚开始的时候绝对没有图形化界面&#xff0c;因此操作系统刚开始兴起的时候绝对没有图形化界面&#xff0c;因为当时没有鼠标。 ✨因为没有图形化界面&#xff0c;只有键盘&#xff0c…

vue项目编译、打包、部署服务器运行

在vue项目执行npm run build,生成dis目录 打包dis上传 安装npm install -g http-server或者apt install node-http-server 运行http-server

postman自动化运行接口测试用例

做过接口测试的人&#xff0c;应该都知道postman &#xff0c;我们在日常的时候都可以利用postman做接口测试&#xff0c;我们可以把接口的case保存下来在collection里面&#xff0c;那么可能会有这样的需求&#xff0c;我们怎么把collection的用例放到jenkins中定时执行呢&…

预测宝可梦武力值、分类宝可梦

regression case 股票预测 无人车看到的各种sensor 影像镜头看到马路上的东西作为输入&#xff0c;输出就是方向盘角度等等的操纵策略 scalar 标量 这个是热力图&#xff0c;相当于你的XYZ但是Z用颜色表示了 closed-form solution 闭合解 learning rate事先定好的数值 在lin…

推荐一款简单好用的Bug管理软件

软件开发的速度和质量是企业成功的关键因素&#xff0c;然而随着软件项目的复杂性增加&#xff0c;Bug的管理变得越来越困难。为了解决这个问题&#xff0c;Zoho公司推出了一款强大的Bug管理软件&#xff0c;帮助企业在一个地方记录和跟踪Bug&#xff0c;提高修复效率。 这款名…

10.18~10.22数电第二次实验

频分复用 同一个时间共用一个频道&#xff0c;只不过频率不同&#xff0c;所以互不影响 时分复用 不同时间公用一个频道&#xff0c;轮流使用 时分复用&#xff08;TDM&#xff0c;Time-division multiplexing&#xff09;就是将提供给整个信道传输信息的时间划分成若干时间…

SQL基础语法总结(查询)

学习网站&#xff1a;https://www.w3schools.com/sql/&#xff0c;提供在线编程 以下内容仅SQL常见语法总结 数据 Customers表 Products表 OrderDetails表 Orders表 Shippers表 Employees表 选择查询 SELECT select语句用来从头数据库中选择数据 SELECT column1, column2,…

交换机/防火墙-基础配置-23.10.11

1.MAC地址 交换机在给主机之间传递信息包时&#xff0c;通过MAC地址来标识每台主机 主机间发生信息包交换时&#xff0c;交换机就会将通信过的主机的mac地址存下 dis mac-address 交换机转发的数据包中&#xff0c;会包含一个目标MAC&#xff0c;交换机识别数据包中的目标MA…

可视化数学分析软件 MATLAB R2021b mac中文版软件介绍

MATLAB R2021b mac作为数学类科技应用软件中首屈一指的商业数学软件&#xff0c;可以帮助您进行矩阵运算、绘制函数和数据、实现算法、创建用户界面、连接其他编程语言的程序等,主要应用于工程计算、控制设计、信号处理与通讯、图像处理、信号检测、金融建模设计与分析等领域。…

自己动手写编译器:c 语言模板中的输入模块设计

使用过“框架”的同学都能感受到“框架”带来的方便。所谓”框架“本质上就是一系列代码安排帮助我们完成脏活累活&#xff0c;或者复杂的工作流程后&#xff0c;把处理结果交给我们提供的代码。本节我们要完成的 c 语言模板也是一个框架&#xff0c;它也需要做一系列脏活累活&…

vue重修之路由【上】

文章目录 单页应用程序: SPA - Single Page Application路由简介Vue Reouter简介VueRouter的使用&#xff08;52&#xff09;组件的存放目录问题组件分类存放目录 路由的封装抽离 单页应用程序: SPA - Single Page Application 单页面应用(SPA): 所有功能在 一个html页面 上 单…

【Java 进阶篇】深入了解 Bootstrap 全局 CSS 样式

Bootstrap 是一个流行的前端框架&#xff0c;以其强大的全局 CSS 样式而闻名。这些样式能够帮助开发者快速创建漂亮的、响应式的网页&#xff0c;而无需从头编写复杂的 CSS。在本文中&#xff0c;我们将深入探讨 Bootstrap 的全局 CSS 样式&#xff0c;适合初学者&#xff0c;帮…

最新AI创作系统ChatGPT源码+搭建部署教程+支持GPT4.0+支持ai绘画(Midjourney)/支持Prompt

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统AI绘画系统&#xff0c;支持OpenAI GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署…