C++教程之迭代器Iterator
前言
之前的两篇文章我们主要了解了vector和string的相关知识,从中我们知道可以通过下标来访问vector的元素或者string的字符,但是除了这种方式还有一种更为通用的方式获取元素,那就是迭代器,这篇文章就会简单介绍迭代器的相关内容。
迭代器简介
在我们使用容器去存储元素的时候有时候会需要获取存储的元素,而迭代器就是用于从容器中获取元素的,基本上所有容器的库都支持迭代器,但是只有其中一小部分支持下标获取元素的。虽然string不是容器但是其支持很多容器的操作,其中就包括下标和迭代器。
与指针类似,迭代器提供了一种间接获取对象的方式,对于迭代器而言,这个对象就是容器中的元素或者string中的字符,我们可以通过迭代器获取一个元素,与此同时也可以将指向的对象从一个对象移到下一个对象。迭代器还和指针一样有有效和无效之分,所有代表容器中元素或最后一个元素的下一个位置都是有效的,其他所有的迭代器都是无效的。
迭代器的使用
不像指针,我们不使用地址操作符去获取一个迭代器,每一个支持迭代器的类型都有函数可以返回迭代器,这些类型都有名为begin和end的函数,begin返回的是代表第一个元素的迭代器,end的返回的迭代器是容器或者字符串的最后一个元素的下一个位置,这个迭代器代表着最后一个元素的下一个位置,是一个不存在的元素。如果容器为空,则begin和end返回的是同一个迭代器。
auto b = v.begin(), e = v.end()
迭代器的操作
迭代器只支持下表列出来的操作,我们可以通过==或!=比较两个有效的迭代器,如果迭代器代表着同一个元素或者都是最后一个元素的下一个位置则相等,否则它们不等。
|操作|解释|
|*iter|返回迭代器代表的指针指向的值|
|iter->mem|等价于(*iter).mem|
|++iter|指向容器中的下一个元素|
|–iter|指向容器中的前一个元素|
|iter1 == iter2|判断两个迭代器是否相等|
|iter1 != iter2|判断两个迭代器是否不等|
对于指针,我们可以使用解引用符获取一个迭代器的元素,和指针相同,我们只能通过解引用符获取一个有效的迭代器的元素,如果解引用一个最后一个元素之后的迭代器结果是未知的。
# include<iostream>
# include<string>
using namespace std;int main() {string s("some string");if (s.begin() != s.end()) {auto it = s.begin();*it = toupper(*it);}cout<<s<<endl;}
上述的例子就是通过迭代器获取字符串s的首个字符并将其大写。
迭代器从一个元素移动到另一个元素
迭代器私用自增操作符从一个元素移动到该元素的下一个元素,自增一个迭代器与自增一个整型十分类似,对于整型而言,自增的是其本身的值,对于迭代器而言,其影响是往前进一个位置。
由于end返回的不是一个元素,所以其不能自增或者解引用
使用自增操作我们可以重写之前的程序:
# include<iostream>
# include<string>
using namespace std;int main() {string s("some string");for (auto it = s.begin(); it != s.end() && !isspace(*it); ++it) {*it = toupper(*it);}cout<<s<<endl;}
如上例所示,我们通过迭代器可以实现循环遍历。
迭代器的类型
正如我们并不准确知道vector的准确类型或者string的size,同样的,我们也不知道同时也不需要知道迭代器的准确类型,但是根据迭代器的读写权限定义了以下几种迭代器的类型:
vector<int>::iterator it; //it可以读也可以写vector<int>的元素string::iterator it2; //it2可以读写字符串里的字符vector<int>::const_iterator it3; //it3可以读但是不可以写元素string::const_iterator it4; //it4可以读但是不可以写字符串里面的字符
const_iterator表现就像是常量指针,可以读取元素但是不能写元素
begin和end操作
begin和end返回的结果取决于它们操作的对象是不是常量,如果操作对象是常量,那么begin和end返回的就是const_iterator,如果对象不是常量,那么返回的就是iterator。
# include<iostream>
# include<string>
# include<vector>
using namespace std;int main() {
vector<int> v;
const vector<int> cv;
auto it1 = v.begin(); //it返回的是vector<int>::iterator
auto it2 = v.begin(); //it返回的是vector<int>::const_iterator
}
这种默认的返回策略有时候并不满足需求,在一些情况下一些非常量的vector我们只想读取元素,避免元素被更改,在C++11中提供了以下新的方法cbegin和cend,无论vetor是不是常量都返回const_iterator。
auto it3 = v.cbegin();
迭代器的数学运算
处理之前提到自增和自减外,迭代器还支持以下数学运算,虽然迭代器是没有下标的概念的,但是一下运算都可以理解为是对于下标的操作,如加减就是自增和自减的普通形式,就是向前移动或者向后移动,大小比较就是前后位置的比较。
| 操作 | 解释 |
|---|---|
| iter + n | 同一个容器向前移动n |
| iter - n | 同一个容器向后移动 |
| iter1 += n | 将移动结果赋值给iter1 |
| iter1 -= n | 将移动结果赋值给iter1 |
| >, >=, <, <= | 相对位置的比较 |
这么说起来可能又带你抽象,下面用一个二分法来说明:
# include<iostream>
# include<string>
# include<vector>
using namespace std;int main() {vector<int> v = {1, 2, 3, 4, 5};auto beg = v.begin(), end = v.end();auto mid = v.begin() + (end - beg) / 2;int target = 2;while (mid != end && *mid != target){if (target < *mid) {end = mid;} else{beg = mid;}mid = beg + (end - beg) / 2;}cout<<to_string(*mid)<<endl;}
以上例子会打印2,也就是元素2的位置。
最后
这篇文章主要介绍了C++中的迭代器,更多文章可以关注公众号QStack。
相关文章:
C++教程之迭代器Iterator
前言 之前的两篇文章我们主要了解了vector和string的相关知识,从中我们知道可以通过下标来访问vector的元素或者string的字符,但是除了这种方式还有一种更为通用的方式获取元素,那就是迭代器,这篇文章就会简单介绍迭代器的相关内…...
容联七陌:ChatGPT大模型能力为智能客服带来新方向
科技云报道原创。 近几个月来,大众对ChatGPT预期的持续走高,也影响到了智能客服领域公司的命运。 一方面,ChatGPT的出现为智能客服场景带来了更加“智能”的可能性;但另一方面,有人认为ChatGPT完全可以替代现有的智能…...
【Linux 多线程同步】使用同步和互斥实现生产消费模型
目录 1.同步的接口 2.多线程但是按顺序来执行 3.生产消费模型 4.使用互斥加同步实现生产消费模型 (采用环形队列) 同步:在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从而有效避免饥饿问题 …...
【TypeScript】TypeScript的接口和对象类型(interface):
文章目录一、使用接口约束的时候不能多一个属性也不能少一个属二、重名interface 可以合并,继承三、可选属性 使用?操作符四、任意属性 [propName: string]五、只读属性 readonly,是不允许被赋值的只能读取六、添加函数一、使用接口约束的时候不能多一个…...
7、函数与异常
目录一、函数的概念二、匿名函数三、闭包四、defer五、异常机制一、函数的概念 函数的基本形式 //函数定义。a,b是形参 func argf(a int, b int) { a a b } var x, y int 3, 6 argf(x, y) //函数调用。x,y是实参函数参数: func arg2(a, b int) { //参数类型相…...
Julia 语言环境安装
Julia 语言支持以下系统: LinuxFreeBSDmacOSWindowsAndroid Julia 安装包下载地址为:Download Julia。 Github 源码地址:GitHub - JuliaLang/julia: The Julia Programming Language。 国内镜像地址:Index of /julia-releases/…...
5.1 线程
文章目录1.概述2.多线程的特性2.1 随机性2.2 CPU分时调度2.3 线程的状态2.4 线程状态与代码对照3.多线程代码实现方式1:继承Thread3.1 概述3.2 常用方法3.3 测试多线程的创建方式14.多线程代码实现方式2:实现Runnable接口4.1 概述4.2 常用方法4.3 练习2:测试多线程的…...
通讯录的实现
一、目的:使用C实现通讯录二、包含功能:添加联系人:向通讯录中添加新人,信息包括(姓名、性别、年龄、联系电话、家庭住址)最多记录1000人显示联系人:显示通讯录中所有联系人信息删除联系人:按照姓名进行删除指定联系人…...
Urho3D导航
Urho3D通过使用Recast和Detour库实现导航网格生成和路径查找。 导航功能通过NavigationMesh和Navigable组件公开。 NavigationMesh从已使用Navigable组件标记的子节点收集几何体。默认情况下,可导航组件的行为是递归的:除非禁用递归,否则也…...
【学习总结】激光雷达与相机外参标定:代码(cam_lidar_calibration)
前段时间尝试了一款激光雷达和相机标定的代码,总结了博客: 【学习总结】激光雷达与相机外参标定:原理与代码 但总觉得那个代码太差劲,而且精度不行,于是又找了些新的代码,体验比之前的好很多,在…...
车载技术开发—{Android CarFrameWork}
Android Automotive平台 Android Automotive是通过Android的通用框架,语言和API来实现的一个全栈,开源,高度可定制的平台。 Android Automotive与整个Android生态系统的关系 Android Automotive是Android的一部分。 Android Automotive不是…...
多城市二手车买卖发布管理小程序开发
多城市二手车买卖发布管理小程序开发 功能特性: 为你介绍二手车微信小程序的功能特性。 车辆分类搜索,支持按品牌、售价、年龄、上牌时间、排量等筛选。 车源发布,支持用户一键发布二手车,平台审核上线,发布可编辑、删除等操作。…...
企业级信息系统开发学习笔记1.2 初探Spring——利用组件注解符精简Spring配置文件
文章目录零、本讲学习目标一、课程引入二、打开项目 - SpringDemo三、利用组件注解符精简Spring配置文件(一)创建新包(二)复制四个类(三)修改杀龙任务类(四)修改救美任务类ÿ…...
37、基于51单片机乒乓球比赛系统设计
摘要 乒乓球游戏电路是一个对输入信号、输入时机正确与否的8个LED表示乒乓球球台和乒乓球,用数码管模拟显示器,显示比赛局数比分和每局玩家得分的电路。电路并不复杂,整体分为两个模块:一,游戏主模块;二&a…...
VMware虚拟机安装Win11最详细过程以及遇到的这台电脑无法运行Windows11的问题
准备工作 在使用VMware虚拟机安装Win11之前我们先把准备工作做好,以免后续思绪混乱导致出错。 1. 到VMware官网或点击链接下载正版VMware Workstation 16 Pro。 2. 双击打开安装包,点击下一步。 3. 阅读用户许可协议,勾选我接受许可协议中的…...
centos误删python2后怎么重新安装
此教程为离线安装 一. 先查询系统版本 cat /proc/version Linux version 3.10.0-1127.el7.x86_64 (mockbuildkbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC) ) #1 SMP Tue Mar 31 23:36:51 UTC 2020 二. 安装python2.7.5(已知原python版…...
Qt 开发使用VSCode 笔记2
在之前有写过使用VSCode开发QT的笔记 Qt 开发使用VSCode 在以前的基础上继续学习记录写下《Qt 开发使用VSCode 笔记2》 该笔记相比之前的Qt 开发使用VSCode新加了如下内容: 工作区的使用使用Natvis进行Qt感知对象可视化通过vscode创建QT Quick项目 工作区的使用 …...
查找算法复习
先序在了解查找算法之前,需要熟悉几个概念,不然后面容易产生理解错误。查找表:即被查找的对象,通常由几个关键字组成。关键字:就是数据项、字段的意思。关键字有主次之分,其中主关键字取值是唯一的。查找长…...
腾讯前端必会面试题(必备)
如何提取高度嵌套的对象里的指定属性? 有时会遇到一些嵌套程度非常深的对象: const school {classes: {stu: {name: Bob,age: 24,}} }像此处的 name 这个变量,嵌套了四层,此时如果仍然尝试老方法来提取它: const {…...
探访上汽通用武汉奥特能超级工厂
上汽通用汽车在电动化和智能网联化新技术领域投入了700亿大洋,武汉奥特能超级工厂就是其中一个重点项目。这个工厂已经投产,将成为上汽通用汽车的新能源生产基地,加速奥特能平台车型的推出。 最近别克推出了Electra E5,它是别克第…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)
LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 题目描述解题思路Java代码 题目描述 题目链接:LeetCode 3309. 连接二进制表示可形成的最大数值(中等) 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
基于鸿蒙(HarmonyOS5)的打车小程序
1. 开发环境准备 安装DevEco Studio (鸿蒙官方IDE)配置HarmonyOS SDK申请开发者账号和必要的API密钥 2. 项目结构设计 ├── entry │ ├── src │ │ ├── main │ │ │ ├── ets │ │ │ │ ├── pages │ │ │ │ │ ├── H…...
