【C++ STL迭代器】iterator

news2025/3/10 5:50:51

文章目录

  • 【 1. 迭代器的属性 】
  • 【 2. 不同容器支持的迭代器 】
  • 【 3. 迭代器的定义方式 】
  • 【 4. 实例 】
    • 4.1 定义方式:正向迭代器和反向迭代器
    • 4.2 迭代器属性:前向迭代、双向迭代、随机迭代
    • 4.2 迭代器的遍历方法
    • 4.3 auto关键字 自动指定迭代器定义类型

  • 背景
    • 我们知道,尽管不同容器的内部结构各异,但它们本质上都是用来存储大量数据的,换句话说,都是一串能存储多个数据的存储单元。因此,诸如数据的排序、查找、求和等需要对数据进行遍历的操作方法应该是类似的。
    • 既然类似,完全可以利用泛型技术,将它们设计成适用所有容器的通用算法,从而将容器和算法分离开。但实现此目的需要有一个类似中介的装置,它除了要具有对容器进行遍历读写数据的能力之外,还要能对外隐藏容器的内部差异,从而以统一的界面向算法传送数据。
    • 这是泛型思维发展的必然结果,于是迭代器就产生了。简单来讲,迭代器和 C++ 的指针非常类似,它 可以是需要的任意类型,通过迭代器可以指向容器中的某个元素,如果需要,还可以对该元素进行读/写操作。

【 1. 迭代器的属性 】

  • 常用的迭代器按功能强弱分为输入迭代器、输出迭代器、前向迭代器、双向迭代器、随机访问迭代器 5 种。
  • 输入迭代器和输出迭代器
    比较特殊,它们不是把数组或容器当做操作对象,而是 把输入流/输出流作为操作对象
  • 前向迭代器(forward iterator)
    假设 p 是一个前向迭代器,则 p 支持 ++p,p++,*p 操作,还可以被复制或赋值,可以用 == 和 != 运算符进行比较 。此外,两个正向迭代器可以互相赋值
  • 双向迭代器(bidirectional iterator)
    双向迭代器 具有正向迭代器的全部功能,除此之外,假设 p 是一个双向迭代器,则 还可以进行 --p 或者 p-- 操作(即一次向后移动一个位置)
  • 随机访问迭代器(random access iterator)
    随机访问迭代器 具有双向迭代器的全部功能 。除此之外,假设 p 是一个随机访问迭代器,i 是一个整型变量或常量,则 p 还支持以下操作:
    • p+=i:使得 p 往后移动 i 个元素。
    • p-=i:使得 p 往前移动 i 个元素。
    • p+i:返回 p 后面第 i 个元素的迭代器。
    • p-i:返回 p 前面第 i 个元素的迭代器。
    • p[i]:返回 p 后面第 i 个元素的引用。
    • 此外,两个随机访问迭代器 p1、p2 还可以用 <、>、<=、>= 运算符进行比较。另外,表达式 p2-p1 也是有定义的,其返回值表示 p2 所指向元素和 p1 所指向元素的序号之差(也可以说是 p2 和 p1 之间的元素个数减一)。

【 2. 不同容器支持的迭代器 】

  • STL 标准库为每一种标准容器定义了一种迭代器类型,这意味着,不同容器对应的迭代器不同,其功能强弱也有所不同(容器的迭代器的功能强弱,决定了该容器是否支持 STL 中的某种算法)。不同容器对应的迭代器类型如下所示:
容器对应的迭代器类型
array随机访问迭代器
vector随机访问迭代器
deque随机访问迭代器
list双向迭代器
set / multiset双向迭代器
map / multimap双向迭代器
forward_list前向迭代器
unordered_map / unordered_multimap前向迭代器
unordered_set / unordered_multiset前向迭代器
stack不支持迭代器
queue不支持迭代器

容器适配器 stack 和 queue 没有迭代器,它们包含有一些成员函数,可以用来对元素进行访问。

【 3. 迭代器的定义方式 】

  • 尽管不同容器对应着不同类别的迭代器,但这些迭代器有着较为统一的定义方式:
迭代器定义方式具体格式
正向迭代器容器类名::iterator 迭代器名;
常量正向迭代器容器类名::const_iterator 迭代器名;
反向迭代器
(全称:反向迭代器适配器)
容器类名::reverse_iterator 迭代器名;
常量反向迭代器容器类名::const_reverse_iterator 迭代器名;
  • 定义以上几种迭代器后,就可以读取它指向的元素: *迭代器名 就表示迭代器指向的元素。
  • 常量迭代器和非常量迭代器的区别:
    通过非常量迭代器还能修改其指向的元素
  • 反向迭代器和正向迭代器的区别
    • 正向迭代器进行 ++操作 时,迭代器会 指向容器中的后一个元素
    • 反向迭代器进行 ++操作 时,迭代器会 指向容器中的前一个元素
  • 注意,以上 4 种定义迭代器的方式,并不是每个容器都适用。有一部分容器同时支持以上 4 种方式,比如 array、deque、vector;而有些容器只支持其中部分的定义方式,例如 forward_list 容器只支持定义正向迭代器,不支持定义反向迭代器。

【 4. 实例 】

4.1 定义方式:正向迭代器和反向迭代器

  • 以 vector容器 为例,实现正向迭代器和反向迭代器这两种定义方式。
#include <iostream>
#include <vector>
using namespace std;

int main() 
{
    vector <int> vec = {1, 2,3, 4 ,5};
    //正向迭代器
    vector <int>::iterator t1;
    for (t1 = vec.begin(); t1 != vec.end(); ++t1)
        cout << *t1 << " ";
    cout << endl;
    
    //反向迭代器
    vector <int>::reverse_iterator  t2;
    t2 = vec.rbegin();
    for (; t2 != vec.rend(); ++t2)
        cout << *t2 << " ";

    return 0;
}

在这里插入图片描述

4.2 迭代器属性:前向迭代、双向迭代、随机迭代

  • 以 vector 容器为例,vector容器属于随机访问迭代器,也支持前向迭代和双向迭代。表现前向迭代、双向迭代、随机访问迭代三种属性。
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector <int> vec = { 1,2,3,4,5 };
    vector <int>::iterator t;//正向迭代器的定义方式

    //前向迭代,前向迭代器可以实现p++
    for (t = vec.begin(); t != vec.end(); ++t)
        cout << *t << " ";
    cout << endl;
    
    //双向迭代,双向迭代器可以实现p--
    t = vec.end()-1;
    for (int j = 0; j < vec.size(); ++j)
    {
        cout << *t << " ";
        if (t !=vec.begin())  t--;
    }
    cout << endl;

    //随机迭代,随机迭代器可以实现p+i
    t = vec.begin();
    t = t+2;
    cout << *t << " ";

    return 0;
}

在这里插入图片描述

4.2 迭代器的遍历方法

  • 以 vector 容器为例,按照正向迭代器的定义方式,下面的程序中,每个循环演示了一种做法。
//遍历 vector 容器。
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector<int> v{ 1,2,3,4,5,6,7,8,9,10 }; //v被初始化成有10个元素
    vector<int>::iterator i;//创建一个正向迭代器
        
    cout << endl << "第 1 种遍历方法:" << endl;
    for (i = v.begin(); i != v.end(); ++i)//用 != 比较两个迭代器
        cout << *i << " ";

    cout << endl << "第 2 种遍历方法:" << endl;
    for (i = v.begin(); i < v.end(); ++i) //用 < 比较两个迭代器
        cout << *i << " ";

    cout << endl << "第 3 种遍历方法:" << endl;
    i = v.begin();
    while (i < v.end()) 
    {
        cout << *i << " ";
        i += 2; // 随机访问迭代器支持 "+= 整数"  的操作
    }
}

在这里插入图片描述

4.3 auto关键字 自动指定迭代器定义类型

#include <iostream>
#include <vector>
using namespace std;

int main()
{
    vector <int> vec = { 1, 2,3, 4 ,5 };

    auto t = vec.begin();
    for (; t != vec.end(); ++t)
        cout << *t << " ";

    return 0;
}

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Pycharm安装及使用图文教程(附下载地址)

1. Pycharm简介 大家在使用Python的时候往往会选择一款自己熟悉的编译器。大多数Python使用者会选择PyCharm这款软件来进行Python的学习与开发。 关于PyCharm&#xff0c;PyCharm是一种Python IDE&#xff0c;带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具&a…

每日五道java面试题之ZooKeeper篇(一)

目录&#xff1a; 第一题. ZooKeeper 是什么&#xff1f;第二题. Zookeeper 文件系统第三题. Zookeeper 怎么保证主从节点的状态同步&#xff1f;第四题. 四种类型的数据节点 Znode第五题 . Zookeeper Watcher 机制 – 数据变更通知 第一题. ZooKeeper 是什么&#xff1f; Zoo…

Python爬虫:http和https介绍及请求

HTTP和HTTPS 学习目标&#xff1a; 记忆 http、https的概念和区别记忆 浏览器发送http请求的过程记忆 http请求头的形式记忆 http响应头的形式了解 http响应状态码 1 为什么要复习http和https 在发送请求&#xff0c;获取响应的过程中 就是发送http或https的请求&#xff0c…

grep无法使用完整的正则表达式

问题描述 grep无法使用完整的正则表达式&#xff0c;比如前置断言、后置断言、\d和\t、\n等 问题原因 使用了扩展正则&#xff0c;而不是perl正则。规则和perl正则不同 从文档上讲得很清楚&#xff1a; -E PATTERN is an extended regular expression 他是扩展表达式&#…

网络安全 | 什么是负载均衡器?

关注WX&#xff1a; CodingTechWork 介绍 负载均衡是在多个服务器之间有效分配网络流量的过程。负载均衡的目的是优化应用程序的可用性&#xff0c;并确保良好的终端用户体验。负载均衡可协助高流量网站和云计算应用程序应对数百万个用户请求&#xff0c;从而保证客户请求不会…

Driver not loaded之记录Qt访问MySql的解决经历

对于这个问题的本质原因&#xff0c;我也搞不明白&#xff0c;所以记录的方法不一定对所有人行之有效。我的目的很简单&#xff0c;就是把数据库用起来&#xff0c;经过查找网上资料&#xff0c;最终把数据库跑起来了。因此记录如下&#xff1a; 1&#xff0c;出现这个问题是缺…

【Linux】网络基础常识{OSI七层模型/ TCP/IP / 端口号 /各种协议}

文章目录 1.网络常识1.0DHCP协议1. 1IP地址/MAC地址/ARP协议是什么&#xff1f;IP/MACARP&#xff1a;IP ⇒ MAC 1.2手机连接wifi的原理 SSID与BSSID手机连接wifiSSID与BSSID 1.3手机如何通过“数据/流量”上网&#xff1f;1.4电脑连接wifi的原理&#xff1f;电脑通过热点上网…

Linux云计算之Linux基础3——Linux基本认识操作

1、终端 终端(terminal)&#xff1a;人和系统交互的必要设备&#xff0c;人机交互最后一个界面&#xff08;包含独立的输入输出设备&#xff09; 物理终端(console)&#xff1a;直接接入本机器的键盘设备和显示器虚拟终端(tty)&#xff1a;通过软件方式虚拟实现的终端。它可以…

各种滤波算法

各种滤波算法 1. 半径离群点去除(Radius Outlier Removal&#xff0c;半径滤波)2. 统计离群点剔除(Statistical Outlier Removal, 统计滤波)3. 体素网格将采样(voxel grid downsampling)4. 最远点采样(Farthest Point Sampling, FPS)5. 正态空间将采样(Normal Space Sampling, …

第六期丨酷雷曼无人机技能培训

第6期无人机技能提升培训 盼望着盼望着&#xff0c;第六期无人机技能提升培训会终于如期和大家见面了。 2024年1月1日&#xff0c;国务院、中央军事委员会颁布《无人驾驶航空器飞行管理暂行条例》&#xff0c;对民用无人机飞行活动实施更为严格的规范约束&#xff0c;越来越多…

AOP源码解析

一、注册AnnotationAwareAspectJAutoProxyCreator&#xff0c;引入postProcessAfterInitialization 1、Spring 入口&#xff1a; <aop:aspectj-autoproxy /> registerAspectJAnnotationAutoProxyCreatorIfNecessary,注册AnnotationAwareAspectJAutoProxyCreator Annot…

elsint报错Delete `␍`eslintprettier/prettier

一&#xff0c;原因 这篇博客写得很清楚&#xff1a;解决VSCode Delete ␍eslint(prettier/prettier)错误_vscode 删除cr-CSDN博客 还有这篇文章&#xff0c;解决办法很详细&#xff1a;滑动验证页面 二&#xff0c;解决办法 根目录下新建.prettierrc.js文件 module.exports…

wordpress外贸独立站模板

wordpress外贸独立站模板 WordPress Direct Trade 外贸网站模板&#xff0c;适合做跨境电商的外贸公司官方网站使用。 https://www.waimaoyes.com/wangzhan/22.html

入门用Hive构建数据仓库

在当今数据爆炸的时代&#xff0c;构建高效的数据仓库是企业实现数据驱动决策的关键。Apache Hive 是一个基于 Hadoop 的数据仓库工具&#xff0c;可以轻松地进行数据存储、查询和分析。本文将介绍什么是 Hive、为什么选择 Hive 构建数据仓库、如何搭建 Hive 环境以及如何在 Hi…

读《Spring实战》:面向切面

AOP术语 通知&#xff08;Advice&#xff09; 在AOP中&#xff0c;切面的工作被称为通知&#xff0c;也就是通知就是具体要干的工作。 spring中有5中通知&#xff1a; 前置通知&#xff1a; 在目标方法之前调用通知功能后置通知&#xff1a; 在目标方法之后调用通知功能返回…

无线电和雷达频谱大全

1&#xff0c;频率单位 2&#xff0c;全球警用雷达频率 3&#xff0c;军用雷达频段 4&#xff0c;国际电联ITU雷达频段 5&#xff0c;无线电频段 6&#xff0c;电子对抗ECM频段 7&#xff0c;声波频段

C#清空窗体的背景图片

目录 一、涉及到的知识点 1.设置窗体的背景图 2.加载窗体背景图 3.清空窗体的背景图 二、 示例 一、涉及到的知识点 1.设置窗体的背景图 详见本文作者的其他文章&#xff1a;C#手动改变自制窗体的大小-CSDN博客 https://wenchm.blog.csdn.net/article/details/137027140…

基于SpringBoot和Vue的金融融资管理系统的设计和实现【附源码】

1、系统演示视频&#xff08;演示视频&#xff09; 2、需要交流和学习请联系

paddlepaddle模型转换onnx指导文档

一、检查本机cuda版本 1、右键找到invdia控制面板 2、找到系统信息 3、点开“组件”选项卡&#xff0c; 可以看到cuda版本&#xff0c;我们这里是cuda11.7 cuda驱动版本为516.94 二、安装paddlepaddle环境 1、获取pip安装命令 &#xff0c;我们到paddlepaddle官网&#xff…

网络原理 - HTTP / HTTPS(3)——http响应

目录 一、认识 “状态码”&#xff08;status code&#xff09; 常见的状态码 &#xff08;1&#xff09;200 OK &#xff08;2&#xff09;404 Not Found &#xff08;3&#xff09;403 ForBidden &#xff08;4&#xff09;405 Method Not Allowed &#xff08;5&…