C++ 迭代器

迭代器

迭代器类似于指针类型,也提供了对对象的间接访问。
就迭代器而言,其对象是容器中的元素或 string 对象中的字符。

获取迭代器

容器的迭代器类型

使用作用域运算符来说明我们希望使用的类型成员;例:string::iterator iter;

类型别名功能
iterator此容器类型的迭代器
const_iterator可以读取元素,但不能修改元素的迭代器类型
diffreence_type带符号整数类型,足够保存两个迭代器之间的距离
reverse_iterator按逆序寻址元素的迭代器
const_reverse_iterator不允许修改元素的逆迭代器

begin 和 end 成员

和指针不同的是,获取迭代器不适用取地址运算符,有迭代器的类型,同时拥有返回迭代器
的成员函数。
成员函数 begin 生成指向容器中的第一个元素的迭代器。
成员函数 end 生成指向容器中的尾元素之后位置的迭代器(简称尾后迭代器)。

/*获取迭代器,使用 auto 推断迭代器的类型*/string str{ "Hello World" };auto iter_b = str.begin(); auto iter_e = str.end();

begin 和 end 有多个版本:带 r 的版本返回反向迭代器,以 c 开头的版本则返回 const 迭代器。
可以将一个普通的 iterator 转换为对应的 const_iterator,但反之不行。
以 c 开头的版本是C++新标准引入的,用以支持 auto 与 begin 和 end 函数结合使用。

迭代器运算

解引用

可以通过解引用迭代器来获取它所指向的元素。

	string str{ "Hello World" };auto iter = str.begin();cout << *iter << endl; //输出 H 

试图解引用一个非法的迭代器或者尾后迭代器结果都是未定义的。

算数运算

迭代器加上或减去整数

迭代器加上(或减去)一个整数值扔得一个迭代器,迭代器指示的新位置与原来相比向前移动了若干个元素。

	string str{ "Hello World" };auto iter = str.begin();iter = iter + 4;cout << *iter << endl;       // 输出 ocout << *(iter - 3) << endl; // 输出 e

迭代器支持加法(或减法)的复合赋值语句

	string str{ "Hello World" };auto iter = str.begin();iter +=  4;cout << *iter << endl; // 输出 oiter -= 3;cout << *iter << endl; // 输出 e

迭代器支持递增(或递减运算符),表示迭代器指向下一个元素。

	string str{ "Hello World" };auto iter = str.begin();/* 将迭代器向前移动一个元素,然后输出移动后的值 */ cout << *++iter << endl;  // 输出 e/* 将迭代器向后移动一个元素,然后输出移动后的值 */ cout << *--iter << endl;  // 输出 H
两个迭代器可以相减

如果两个迭代器指向同一个容器,则两个迭代器相减的结果是它们之间的距离。

	string str{ "Hello World" };auto iter = str.begin();auto iter_b = iter + 1;auto iter_e = iter + 4;cout << (iter_e - iter_b) << endl; //输出 3
两个迭代器可以比较

如果两个迭代器指向同一个容器,则可以进行比较;指向前面元素的迭代器小于指向后面元素的迭代器。

	string str{ "Hello World" };auto iter = str.begin();auto iter_b = iter + 1;auto iter_e = iter +  4;cout << (iter_b  < iter_e) << endl; //输出 1

如果两个迭代器相等,则两个迭代器指向同一个元素,或者它们是同一个容器的尾后迭代器。

使用迭代器遍历容器

	string str{ "Hello World" };auto it_c = str.cbegin();for (auto iter = str.begin(); iter < it_c + str.size(); iter += 1){cout << *iter;}

迭代器范围

一个迭代器范围(iterator range)由一对迭代器表示,两个迭代器分别指向同一个容器中的元素或者尾元素之后的位置(one past the last element)。
迭代器范围也被称为左闭合区间(left-inclusive interval),其标准数学描述为:[begin end)
标准库使用左闭合范围是因为这种范围有三种方便的性质。
假定 begin 和 end 构成一个合法的迭代器范围,则

  • 如果 begin 和 end 相等,则范围为空。
  • 如果 begin 和end 不相等,则范围至少包含一个元素,且 begin 指向该范围中的第一个元素。
  • 我们可以对 begin 递增若干次,使得begin == end
使用迭代器遍历容器
	string str{ "Hello World" };auto iter = str.begin();while ( iter != str.cend() ){cout << *iter++;}

再探迭代器

除了为每个容器定义的迭代器之外,标准库在头文件<iterator>中还定义额外几种迭代器。这些迭代器包括以下几种:

  • 插入迭代器(insert iterator):这些迭代器被绑定到一个容器上,可用来向容器插入元素。
  • 流迭代器(stream iterator):这些迭代器被绑定到输入或输出流上,可用来遍历所关联的IO流。
  • 反向迭代器(reverse iterator):这些迭代器向后而不是向前移动。除了 forward_list 之外的标准库容器都有反向迭代器。
  • 移动迭代器(move iterator):这些专用的迭代器不是拷贝其中的元素,而是移动它们。

插入迭代器

插入迭代器是一种迭代器适配器,它接受一个容器,生成一个迭代器,能实现向给定容器添加元素。当我们通过一个插入迭代器进行赋值时,该迭代器调用容器操作来给定容器的指定位置插入一个元素。
插入迭代器有三种类型,差异在于元素插入的位置:
back_inserter 创建一个使用 push_back 的迭代器。

	deque <char> D{ 'F','G','H' };auto it = back_inserter(D);/*尾后插入字母 A B C D E */for (char i = 'A'; i < 'F'; ++i){*it = i; //等价于 D.push_back( i );}
/* 队列内的元素变为:F G H A B C D E */

front_inserter 创建一个使用 push_front 的迭代器。

	deque <char> D{ 'F','G','H' };auto it = front_inserter(D);/*首前插入字母 A B C D E */for (char i = 'A'; i < 'F'; ++i){*it = i; //等价于 D.push_front( i );}
/* 队列内的元素变为:E D C B A F G H */

inserter 创建一个使用 insert 的迭代器。此函数接受第二个参数,这个参数必须是一个指向给定容器的迭代器;元素被插入到给定迭代器所表示的元素之前。

	deque <char> D{ 'F','G','H' };auto it = inserter ( D ,D.begin() );for (char i = 'A'; i < 'F'; ++i){*it = i; //等价于 it = D.insert(it,i); ++it; 其中,it = D.begin();}
/* 队列内的元素变为:A B C D E F G H */

iostream 迭代器

虽然 iostream 类型不是容器,但标准库定义了可以用于这些 IO 类型对象的迭代器。
当创建一个流迭代器时,必须指定迭代器将要读写的对象类型。
istream_iterator 读取输入流

	deque <char> D;/*in_iter从输入流 cin 读取类型为 char 的值*/istream_iterator <char> in_iter( cin ); istream_iterator <char> eof; //尾后迭代器while (in_iter != eof){D.push_back( *in_iter++ ); //返回从流中读取的值,然后从流中读取下一个值}

ostream_iterator 向一个输出流写数据
我们可以提供一个(可选的)第二参数,它是一个字符串字面值,在输出每个元素后都会打印此字符串。

	deque <char> D{ 'A','B','C','D','E' };ostream_iterator <char> out_iter (cout, " ");for (auto i : D)out_iter = i; //等价于cout << i << ' ';

反向迭代器

反向迭代器就是在容器中从尾元素反向移动的迭代器。
除了 forward_list 之外,其它容器都支持反向迭代器。
成员函数 rbegin 返回指向容器尾元素的迭代器。
成员函数 rend 返回指向容器首元素之前位置的迭代器。
反向迭代器迭代器也有 const 版本,即 crbegin 和 crend。

使用反向迭代器逆序遍历容器
	deque <char> D{ 'A','B','C','D','E' };auto it = D.crbegin();while (it != D.crend()){cout << *it++ << ' ';}

泛型算法结构

任何算法的最基本的特征是它要求其迭代器提供哪些操作。
算法所要求的迭代器操作可以分为 5 个迭代器类别:

迭代器类别特点
输入迭代器只读,不写;单遍扫描,只能递增
输出迭代器只写,不读;单遍扫描,只能递增
前向迭代器可读写;多遍扫描,只能递增
双向迭代器可读写;多遍扫描,可递增递减
随机访问迭代器可读写;多遍扫描,支持全部迭代器运算

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

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

相关文章

探秘MSSQL存储过程:功能、用法及实战案例

在现代软件开发中&#xff0c;高效地操作数据库是至关重要的。而MSSQL&#xff08;Microsoft SQL Server&#xff09;作为一款强大的关系型数据库管理系统&#xff0c;为我们提供了丰富的功能和工具来处理数据。其中&#xff0c;MSSQL存储过程是一项强大而又常用的功能&#xf…

改进YOLOv8注意力系列一:结合ACmix、Biformer、BAM注意力机制

🗝️改进YOLOv8注意力系列一:结合ACmix、Biformer、BAM注意力机制 代码ACmixBiFormerBAMBlock加入方法各种yaml加入结构本文提供了改进 YOLOv8注意力系列包含不同的注意力机制以及多种加入方式,在本文中具有完整的代码和包含多种更有效加入YOLOv8中的yaml结构,读者可以获…

C++ 的关键字(保留字)介绍

一.C中部分关键字的用法 1. auto 关键字auto是C11引入的&#xff0c;它可以用于变量声明和函数返回类型的推导。当你不关心变量的具体类型时&#xff0c;可以使用auto来让编译器根据初始化表达式推导出变量的类型。这样可以简化代码&#xff0c;提高可读性。 1.在for循环中遍…

Mysql索引一篇就够了

索引 定义 索引是对数据库表中一列或者多列的值进行排序的结构。 目的 数据库索引好比一本书的目录&#xff0c;提高查询效率。但是为表设置索引要付出相应的代价&#xff1a; 增加了数据库的存储空间 在插入和修改时需花费更多的时间&#xff08;因为索引也要随之变动&#…

一、C#笔记

1.注释 /*多行注释*/class HelloWorld{ void Hello(){Console.WriteLine("Hello!");//单行注释}} 2.理解语句 2.1方法、语法、语义 2.2使用标识符 标识符语法规则&#xff1a; 只能使用字母&#xff08;大写和小写&#xff09;、数字和下划…

C++相关闲碎记录(5)

1、容器提供的类型 2、Array Array大小固定&#xff0c;只允许替换元素的值&#xff0c;不能增加或者移除元素改变大小。Array是一种有序集合&#xff0c;支持随机访问。 std::array<int, 4> x; //elements of x have undefined value std::array<int, 5> x {…

渗透测试——七、网站漏洞——命令注入和跨站请求伪造(CSRF)

渗透测试 一、命令注入二、跨站请求伪造(CSRF)三、命令注入页面之注人测试四、CSRF页面之请求伪造测试 一、命令注入 命令注入(命令执行) 漏洞是指在网页代码中有时需要调用一些执行系统命令的函数例如 system()、exec()、shell_exec()、eval()、passthru()&#xff0c;代码未…

基于ssm在线云音乐系统的设计与实现论文

摘 要 随着移动互联网时代的发展&#xff0c;网络的使用越来越普及&#xff0c;用户在获取和存储信息方面也会有激动人心的时刻。音乐也将慢慢融入人们的生活中。影响和改变我们的生活。随着当今各种流行音乐的流行&#xff0c;人们在日常生活中经常会用到的就是在线云音乐系统…

走迷宫(详细分析)

目录 一、课题描述 输入样例&#xff1a; 输出样例&#xff1a; 二、需求分析 输入的形式和输入值的范围&#xff1a; 输出的形式&#xff1a; 程序所能达到的功能&#xff1a; 三、概要设计 四、流程图 五 、代码详细注释 六、测试数据和结果 一、课题描述 以一个…

freeswitch webrtc video_demo客户端进行MCU的视频会议

系统环境 一、编译服务器和加载模块 二、下载编译指定版本video_demo 三、配置verto.conf.xml 1.修改配置文件 2.重新启动 四、MCU通话测试 1.如何使用video_demo 2.测试结果 五、MCU的通话原理及音频/视频/布局/管理员等参数配置 附录 freeswitch微信交流群 系统环境 lsb_rel…

MyBatis处理映射关系

在Mybatis实现数据处理过程中&#xff0c;字段名符合数据库的规则&#xff0c;属性一般为驼峰规则&#xff0c;因此字段名和属性名通常不一致&#xff0c;此时可以通过以下两种方式对数据库字段进行映射处理&#xff1a; 为字段起别名&#xff0c;保证和实体类中的属性名一致在…

lv11 嵌入式开发 IIC(下) 20

目录 1 Exynos4412下IIC控制器介绍 1.1 总览 1.2 特征 1.3 工作框图 1.4 其他内容介绍 1.5 四种工作模式寄存器流程 2 IIC寄存器详解 2.1 概述 2.2 控制寄存器 2.3 状态寄存器 2.4 地址寄存器 2.5 数据寄存器 2.6 其他寄存器 3 MPU06050 3.1 简介 3.2 MPU6050主…

HJ103 Redraiment的走法

题目&#xff1a; HJ103 Redraiment的走法 题解&#xff1a; dfs 暴力搜索 枚举数组元素&#xff0c;作为起点如果后续节点大于当前节点&#xff0c;继续向后搜索记录每个起点的结果&#xff0c;求出最大值 public int getLongestSub(int[] arr) {int max 0;for (int i 0…

data_loader返回的每个batch的数据大小是怎么计算得到的?

data_loader是一个通用的术语&#xff0c;用于表示数据加载器或数据批次生成器。它是在机器学习和深度学习中常用的一个概念。 一、data loader 数据加载器&#xff08;data loader&#xff09;是一个用于加载和处理数据集的工具&#xff0c;它可以将数据集划分为小批次&#…

提示(Prompt)工程中提示词的开发优化基础概念学习总结

本文对学习过程进行总结&#xff0c;仅对基本思路进行说明&#xff0c;结果在不同的模型上会有差异。 提示与提示工程 提示&#xff1a;指的是向大语言模型输入的特定短语或文本&#xff0c;用于引导模型产生特定的输出&#xff0c;以便模型能够生成符合用户需求的回应。 提示…

内存学习——堆(heap)

目录 一、概念二、自定义malloc函数三、Debug运行四、heap_4简单分析4.1 heap管理链表结构体4.2 堆初始化4.3 malloc使用4.4 free使用 一、概念 内存分为堆和栈两部分&#xff1a; 栈&#xff08;Stack&#xff09;是一种后进先出&#xff08;LIFO&#xff09;的数据结构&…

AVFormatContext封装层:理论与实战

文章目录 前言一、封装格式简介1、FFmpeg 中的封装格式2、查看 FFmpeg 支持的封装格式 二、API 介绍三、 实战 1&#xff1a;解封装1、原理讲解2、示例源码 13、运行结果 14、示例源码 25、运行结果 2 四、 实战 2&#xff1a;转封装1、原理讲解2、示例源码3、运行结果 前言 A…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《考虑电力-交通交互的配电网故障下电动汽车充电演化特性》

这个标题涉及到电力系统、交通系统和电动汽车充电的复杂主题。让我们逐步解读&#xff1a; 考虑电力-交通交互的配电网故障&#xff1a; 电力-交通交互&#xff1a; 指的是电力系统和交通系统之间相互影响、相互关联的关系。这可能涉及到电力需求对交通流量的影响&#xff0c;反…

回溯算法之N皇后

一 什么是回溯算法 回溯算法&#xff08;Backtracking Algorithm&#xff09;是一种用于解决组合优化问题的算法&#xff0c;它通过逐步构建候选解并进行验证&#xff0c;以寻找所有满足特定条件的解。回溯算法通常应用于在给定约束条件下枚举所有可能解的问题&#xff0c;如…

Git—文件添加查看删除修改

目录 1.添加文件—场景一 2.查看.git文件 3.添加文件—场景三 4.修改文件 5.版本回退 6.撤销修改 7.删除文件 1.添加文件—场景一 在包含.git的目录下新建⼀个ReadMe文件&#xff0c;我们可以使用 git add 命令可以将文件添加到暂存 区&#xff1a; ●添加一个或多个文…