C++相关概念和易错语法(12)(迭代器、string容量调整)

1.迭代器(以string为例)

(1)基本理解:在我们刚接触迭代器的时候,我们可以将迭代器理解为改造过的“指针”,这是一个新的类型,指向对应容器中的各个元素。我们可以像指针那样对迭代器进行++,*等操作,只不过++是指向下一个元素而非下一个字节,*得到的是对应的元素而非一个字节的内容。我们发现虽然迭代器并不能完全和指针划等号,但是它们的功能基本相同,而且在迭代器更安全、方便,支持所有容器,因此它是主流、通用的访问方式。

(2)begin、end:

begin和end是对应类的成员函数,在不同容器有不同的实现方法。

要得到对应容器的迭代器,我们需要调用实例化对象的成员函数。

80fb69a5e851411f892dbf0cec8363e3.png

迭代器在不同的容器里面访问的大小、方式都有所区别,因此迭代器是根据不同容器设计的,所以注意迭代器类型前面要确定类域,写作string::iterator

同样我们也可以获取末尾元素(有效字符)的下一个元素\0的迭代器

注意左闭右开的规则,不要越界访问,虽然我们知道\0也是字符串的一部分,本质上说也不算越界,但是考虑到实际使用没正常人会去对这个\0动手脚(如果单独改了这个\0,就会导致字符串没有\0,会引发一系列隐患),所以只要访问\0或者越界,就会断言。

(3)范围for的运用

利用迭代器,我们可以很轻松的访问对象里面的数据,就像指针一样。

但我们还有其它更简洁的方法。

C++借鉴了其它语言的范围for用法,使用for (type e : arr)可以快速遍历数组,不会发生越界,也不需要自己去算数组的大小,很方便。范围for的实现本质上是迭代器,遍历的时候是自动调用函数begin得到初始位置的迭代器并“解引用”,自动++直到和end迭代器相同为止,这也是范围for知道从哪里开始,从哪里结束的原因。因此我们可以应用于string中,实现快速遍历。

这里值得注意的是,我们得到迭代器后可以对对应的数据进行修改,这并没有影响封装的特性,因为迭代器本身就是类里面定义出来的,修改数据的手段受到迭代器本身的限制(不能随便针对某个字节进行修改,只能对有效部分的数据修改),数据方法集为一体。

注意要使用引用才能修改,否则e是临时变量

而相对应的,c_str得到的就是string的地址,我们不能修改解引用的值,因为这个时候如何修改完全不受控制,会影响封装的特性。

(4)iterator begin() 和 const_iterator begin() const 的区别

我们要注意,迭代器根据访问权限的区别分为了iterator和const_iterator,这和指针一样,限制在于加了const的迭代器没有办法进行解引用再修改值的操作,也就是只读不写。一般当我们使用const string实例化对象的时候就只能用const_iterator,其调用的所有成员函数后面都要有const修饰(修饰的是this指针)

其中s.end()会去自动调用匹配const_iterator end() const,原因在于end成员函数构成了函数重载,会根据this的类型去自动匹配合适的。

​​​​​​​但是注意有无const修饰的迭代器之间不能隐式类型转换。如果接收返回值的迭代器类型错误的话,会报错。

可能还有人会混淆const_iterator和const iterator。const iterator修饰的是iterator,即不能修改iterator本身,那么迭代器本身就失去了意义,所以没有这种迭代器。const_iterator修饰的是iterator解引用后的值,不能修改。这个区别和指针的const规则类似,只不过指针是根据const和*的相对位置来区分的,迭代器iterator就一个单词,不存在相对位置的概念,所以使用const_放在iterator前面表示区分。

(5)反向迭代器

反向迭代器和正向迭代器的主要区别在于反向迭代器是用于从后向前遍历的。

当我们用rbegin时,得到的是串中最后一个有效字符(不包含\0)

而rend返回的是串中第一个字符的前一个理论字符的迭代器(这个字符不存在,是假设出来的,这里实际上已经越界了,和end有区别)

值得注意的是返回的迭代器类型是反向的,和正向的不相通

反向迭代器的其它特性和正向迭代器的相同,都存在const修饰问题。即返回值reverse_iterator和const_reverse_iterator,这里就不重复讲它们的区别了。

但是反向迭代器不能直接支持范围for,范围for自动调用的是正向迭代器,即从前向后遍历。

我们只有自己手动实现从后向前遍历。

在这里我们也可以看到正反迭代器之间的区别。当我们++时,反向迭代器的变化相当于正向迭代器的--

2.扩容

当我们要读取整个文件的字符并把它存到string中时,我们发现如果什么都不处理,默认情况下string会进行多次扩容,扩容意味着多次移动数据,涉及多次数据复制,大大影响了性能。所以在有预见的情况下,我们可以手动扩容,一次性申请大一点的空间,这样挪动数据的消耗就很小。

​​​​​​​(1)capacity、size

要理解扩容,我们需要对capacity、size有一定了解。

当我们创建string对象时,capacity和size也随之生成,这和顺序表一致,当我们存入数据时,size会增加,数据超过一定量时,会出现扩容。扩容的时候capacity也会随之变大。

注意size指向的是\0对应的下标,也就是有效数据的下一个,capacity也是指有效空间,但它其实多开辟了一个用来存\0

当使用迭代器的时候,就会受到size的限制,当迭代器指向的数据下标大于等于size对应的值时,就会判定为越界,等于size时指向的就是\0

和顺序表一样,capacity表示的是实际开辟的空间-1(有效空间,为\0预留一个字节),但是超过size的就无法访问

(2)reserve

reserve就是提前开辟空间,修改capacity的函数,它的好处在于一次性就开辟这么多空间,capacity不会再轻易地变化了。也就是说对数据的转移会减少,能有效提高程序效率。

你会发现,capacity实际的大小不是1000,这是编译器自己的处理,我们用去过分关心。

但是提前开辟空间并不代表这块空间能够被访问。虽然我们看到capacity变大了,但size并不会改变,迭代器的访问范围依旧限制在扩容前的范围内。

(3)resize

resize也是提前开辟空间的一个函数,但是它和reserve有本质区别。reserve是预开辟空间,这块空间不能被访问,不会对现有的串造成影响,访问范围也不会改变。

但resize在开辟空间,修改capacity后,还会修改size,直接扩充了我们访问的范围。

我们发现扩容后,size直接跳到100,意味着0~99的数据都能被正常访问,在默认情况下,扩容后的空位补\0,你也可以指定字符。

用resize还是reserve要根据具体情况具体分析,resize用于扩容的时候要慎用,因为它的参数的意思是将string扩充到n个字节而不是预开辟n个字节,之后填充数据是直接从size开始,这很容易出现浪费空间的情况。

3.缩容

(1)缩容的话不推荐使用reserve,在有的编译器低下什么事都不会做

(2)resize能缩容,是将多余的数据直接抛弃,将size定位到设置的值

当缩容时,resize后的第二参数没有意义

(3)shrink_to_fit

这个函数是将capacity往下减少但不改变原有数据和size,防止空间开辟了太多占着不用。

但是这个函数本质上是用时间换空间,看似只修改了capacity,实际上这还涉及空间的归还,数据挪动,很浪费资源,所以一般不要用。

我们可以在reserve开辟过多的情况下使用shrink_to_fit调整

我们还能知道,resize浪费的空间无法通过shrink_to_fit来释放,所以一定要注意resize扩容的操作

​​​​​​​

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

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

相关文章

Lombok介绍、使用方法和安装

目录 1 Lombok背景介绍 2 Lombok使用方法 2.1 Data 2.2 Getter/Setter 2.3 NonNull 2.4 Cleanup 2.5 EqualsAndHashCode 2.6 ToString 2.7 NoArgsConstructor, RequiredArgsConstructor and AllArgsConstructor 3 Lombok工作原理分析 4. Lombok的优缺点 5. 总结 1 …

Idea入门:一分钟创建一个Java工程

一,新建一个Java工程 1,启动Idea后,选择 [New Project] 2,完善工程信息 填写工程名称,根据实际用途取有意义的英文名称选择Java语言,可以看到还支持Kotlin、Javascript等语言选择包管理和项目构建工具Mav…

LVS的三种工作模式---(DR/TUN/NAT)

目录 一、NAT模式(LVS-NAT) 二、IP隧道模式(LVS-TUN) 三、DR模型--直接路由模式(LVS-DR) LVS/DR模式ARP抑制 原因: LVS的DR工作模式及配置: LVS的NAT工作模式及配置&#xff1…

PyQt6--Python桌面开发(7.QTextEdit多行富文本框控件)

QTextEdit多行富文本框控件 保存文件到本地QLine多行文本框.ui import sys import time from PyQt6.QtGui import QValidator,QIntValidator from PyQt6.QtWidgets import QApplication,QLabel,QLineEdit,QTextEdit from PyQt6 import uic,QtGuiif __name__ __main__:appQApp…

二叉树进阶 --- 上

目录 1. 二叉搜索树的概念及结构 1.1. 二叉搜索树的概念 1.2. 二叉搜索树的结构样例 2. 二叉搜索树的实现 2.1. insert 的非递归实现 2.2. find 的非递归实现 2.3. erase 的非递归实现 2.3.1. 第一种情况:所删除的节点的左孩子为空 2.3.1.1. 错误的代码 2…

基本QinQ

拓扑图 配置 开启LLDP功能,查看是否能通过QinQ隧道透传 sysname AR1 # lldp enable # interface GigabitEthernet0/0/0.10dot1q termination vid 10ip address 12.1.1.1 255.255.255.0 arp broadcast enable # sysname AR2 # lldp enable # interface GigabitE…

地磁暴红色预警来袭,普通人该如何应对?绝绝子的防护指南来了

近日,国家空间天气监测预警中心发布了一则令人瞩目的消息——地磁暴红色预警。这一预警不仅提醒我们地磁暴即将影响我国的电离层和低轨卫星,更让我们深刻认识到地球空间环境的脆弱性和复杂性。对于普通公众而言,地磁暴的概念可能相对陌生&…

【每日刷题】Day37

【每日刷题】Day37 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 2391. 收集垃圾的最少总时间 - 力扣(LeetCode) 2. 1614. 括号的最大嵌套深度…

你可能喜欢但也许还不知道的好用网站-搜嗖工具箱

在线工具 https://www.zxgj.cn/ 作为一个工作生活好帮手,在线咨询网站提供了丰富的实用功能,从工作中的图表制作、图片修改到生活中的各种测试、健康、娱乐、学习、理财等等涵盖面很广。 在线工具网站从界面和操作上来看对用户也很友好,页面…

论文研读 An Image Is Worth 16x16 Words: Transformers For Image Recognition At Scale

完整翻译 《An Image is Worth 16x16 Words》完整版翻译_an image is worth 16*16words-CSDN博客 大神讲解 Vision Transformer详解-CSDN博客 视频讲解 11.1 Vision Transformer(vit)网络详解_哔哩哔哩_bilibili 学习整理 简要概述:Vision Transformer&#xff…

在 Kubernetes 上运行 Apache Spark 进行大规模数据处理的实践

在刚刚结束的 Kubernetes Community Day 上海站,亚马逊云科技在云原生分论坛分享的“在 Kunernets 上运行 Apache Spark 进行大规模数据处理实践”引起了现场参与者的关注。开发者告诉我们,为了充分利用 Kubernetes 的高可用设计、弹性,在越来…

AIGC (AI-Generated Content) 技术深度探索:现状、挑战与未来愿景

🔥 个人主页:空白诗 文章目录 🤖 AIGC技术:塑造未来的创意与内容革命 🌟引言 🚀AIGC技术发展现状 📈核心技术驱动 💡应用领域拓展 🌐 面临的挑战 ❌真实性与伦理考量 &am…

SAP-CentralFinance - 会计核算中的组织要素 - 学习心得1

1. 定义SAP组织架构和理解各组织架构含义 组织结构遍布SAP 系统的所有重要功能范围。FI 中最重要的组织要素是公司代码。它是“财务会计”中的最小组织单位,可以为其编制自主式完整科目集供外部报告使用。其他重要的组织要素是利润中心业务范围和段。您可以为各个利润中…

大模型微调之 在亚马逊AWS上实战LlaMA案例(十)

大模型微调之 在亚马逊AWS上实战LlaMA案例(十) 训练数据集格式 SageMaker JumpStart 目前支持域适应格式和指令调整格式的数据集。在本节中,我们指定两种格式的示例数据集。有关更多详细信息,请参阅附录中的数据集格式化部分。 …

iview(viewUI) span-method 表格实现将指定列的值相同的行合并单元格

效果图是上面这样的&#xff0c;将第一列的名字一样的合并在一起&#xff1b; <template><div class"table-wrap"><Table stripe :columns"columns" :data"data" :span-method"handleSpan"></Table></div&…

HDFS- DataNode磁盘扩缩容

HDFS- DataNode磁盘扩缩容 背景: 缩减/增加节点磁盘 方案介绍: 采用hdfs dfsadmin -reconfig 动态刷新配置实现,不停服扩缩容。 注意事项: 请在进行缩容之前,务必了解实际的数据量,并确保磁盘有足够的空间来容纳这些数据。还需要考虑未来的使用需求,要预留一定数量的空间…

java+vue3+iclientol实现警务地理信息系统实践

警务地理信息系统&#xff08;Police Geographic Information System, PGIS&#xff09;是一种专为警务工作设计的地理信息系统&#xff0c;它结合了地理信息技术、数据库技术、网络技术和现代警务理念&#xff0c;旨在提升公安机关的空间数据分析、决策支持、指挥调度、案件管…

【QVariant类型剖析】

QVariant类型剖析 &#x1f31f; 官方文档中给出的定义&#x1f31f; 特性&#x1f338;QVariant实战应用&#x1f338;项目成果展示 &#x1f31f; 官方文档中给出的定义 &#x1f4d8;Because C forbids unions from including types that have non-default constructors or…

基于springboot+vue+Mysql的外卖点餐系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

【.NET Core】你认识Attribute之CallerMemberName、CallerFilePath、CallerLineNumber三兄弟

你认识Attribute之CallerMemberName、CallerFilePath、CallerLineNumber三兄弟 文章目录 你认识Attribute之CallerMemberName、CallerFilePath、CallerLineNumber三兄弟一、概述二、CallerMemberNameAttribute类三、CallerFilePathAttribute 类四、CallerLineNumberAttribute 类…