C/C++相关概念和易错知识点(32)(迭代器、string容量调整)

string------各个接口的使用 string,auto,范围for 阅读详情

目录

1.迭代器(以string为例)

(1)基本理解

(2)begin、end

(3)范围for的运用

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

(5)反向迭代器

2.扩容

(1)capacity、size

(2)reserve

(3)resize

3.缩容

(1)reserve

(2)resize

(3)shrink_to_fit


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

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

(2)resize

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

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

(3)shrink_to_fit

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

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

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

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

​​​​​​​

【24届数字IC秋招总结】正式批面试经验汇总6——禾赛 15、ahb写或者读的数据存储起来了嘛,ahb读的话,apb这边是怎样的。19、覆盖率收集的时候有没有哪些是很难收集到的,然后写了定向测试。2、C++有学过嘛 还记得C++的什么内容 C++成绩多少。12、config_db机制用过嘛 四个参数的含义。8、脚本语言有学过嘛 简单学过 简单是指代码数少嘛。13、run_phase和mian_phase的区别。10、覆盖机制的创建方法 ,是不是覆盖用的很少。6、call_back机制记得哪些细节的东西。9、uvm实战学了哪些章节 印象深刻的章节。 阅读详情

相关推荐

sentaurus浪涌仿真sdevice代码解释(4)

9. `Plot(FilePrefix="Surge_n@node@" time=(Range=(0 @<0+10E-3>@) Intervals=10) NoOverWrite)`:设置了一个绘图过程,用于在瞬态分析过程中绘制结果,文件名前缀为`Surge_n@node@`,时间范围从0到`10E-3`秒,每隔10个时间点绘制一次,且不覆盖之前的结果。同样设置了最大迭代次数和线搜索阻尼系数。这个过程将模拟从`0`到`10E-3`秒内器件的行为,并且会在不同的时间点记录和绘制电流和电势的数据。

qq_52640792的博客 1659

Qt 容器类

Sequentail ContainersQVector array-like data structure(在尾部插入数据时效率很高,而在中间和头部插入数据时开销很大)。QVector提供了[]运算符QVector可以用QVector中的基本类型及指针被初始化为0。QLinkedListQLinkedList不提供[]运算符,所以必须通过迭代器来对其进行遍历。

王以山的专栏 1462

LTspice仿真三线制PT100高精度测温系统设计

本文详细介绍了如何使用LTspice仿真设计三线制PT100高精度测温系统。文章从三线制原理出发,逐步讲解了在LTspice中建模PT100、构建惠斯通电桥进行信号转换、设计差分放大与滤波电路、选型ADC以及进行系统联调与误差分析的全过程,旨在帮助工程师实现0.5°C分辨率的工业测温方案设计。

pz89012345的博客 98

【嵌入式——QT】容器类

嵌入式-QT-容器类

weixin_39723539的博客 2899

基于轻量级神经网络MobileNet V2的水果识别种类算法研究

本文阐述了一种基于轻量级卷积神经网络MobileNet V2的水果分类与识别算法研究。为了最大限度地促进机械收获,需要一个检测系统,它可以让我们识别不同类别的水果。一个相对未开发的想法是使用深度学习和人工智能算法,不仅可以检测水果的种类,还可以检测水果是否成熟。这可以证明是有利可图的,因为它可以提供作物生长状况以及成熟和未成熟果实的个体数量,以及决定是否是收获时间的有用信息。第一步对数据进行了预处理,数据预处理技术在众多的深度学习计算中起到了重要作用。

qq_43556680的博客 1640

pi/4QPSK调制解调原理

文章目录1. π/4\pi/4π/4QPSK 信号的调制原理2. 匹配滤波器与成形滤波器 1. π/4\pi/4π/4QPSK 信号的调制原理 减小相位突变量的QPSK由偏置键控QPSK(OK-QPSK)和 π/4\pi/4π/4偏置的QPSK( π/4\pi/4π/4QPSK)。由于 π/4\pi/4π/4QPSK是用差分相位编码产生的(因此也叫做 π/4\pi/4π/4DQPSK),能有效地进行差分解调和鉴频器解调,在一些不易提取相干载波的场合很有用。 在常规的QPSK中,输入数据经过串/并变换后,分成

gemengxia的博客 2万+

qt end()和Cend() 区别

begin():Return iterator to beginning (public member function ) cbegin():Return const_iterator to beginning (public member function ) 后者返回的是一个不可修改的迭代器,前者可修改。 通俗理解,带C (const)的方法,返回的迭代器不可修改. ...

sinat_26685721的博客 693

YOLOv11 改进 - 注意力机制 | EMA (Efficient Multi-Scale Attention) 高效多尺度注意力:跨空间学习与多分支协同增强特征表征,优化多尺度目标检测

本文介绍了高效多尺度注意力(EMA)模块及其在YOLOv11中的结合应用。现有注意力机制在通道维度缩减时可能影响深度视觉表示,EMA模块通过结合通道和空间信息、采用多尺度并行子网络结构等创新点,实现了高效的多尺度注意力机制。其基本原理包括通道和空间注意力结合、多尺度并行子网络设计等。在多个流行基准数据集上的实验表明,该模块能有效提高特征表示能力。我们将EMA集成进YOLOv11,实验证明改进后的模型在目标检测任务中性能优越,具有广泛应用前景

魔改工程师的博客 1292

C++ 顺序容器学习笔记(一)

容器类型与选择 所有顺序容器都提供了快速顺序访问元素的能力。但是它们的应用有各自优缺点: 像容器添加或从容器中删除元素的代价 像顺序访问容器中元素的代价 注:array的长度是固定的 在实际应用时选择容器的基本原则: 通常,使用vector是最好的选择,除非有特殊需求 如果程序中有很多小的元素,且空间的额外开销很重要,则不要使用list或forward_list 如果程序要求随机访问元素,应使用vector或deque 如果程序要求在容器的中间插入或删除元素,应该使用list或forward_lis

m0_38144614的博客 236

上位机1000条/秒数据不丢不卡:SQLite持久化队列最优方案实战

在上位机每秒1000条、1MB数据的场景下,SQLite做持久化队列是最优解可靠性拉满,ACID事务+WAL模式保证绝对不丢数据;性能完全够用,优化后每秒几千条没问题;轻量无依赖,只有一个.db文件;C#/.NET原生支持,代码简单易维护。只要按照上面的优化点和代码实现,完全能满足工业现场的需求,不用再担心数据丢失、存储卡采集的问题。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 483

华为OD机考双机位C卷 - 补种未成活胡杨 (Java & Python& JS & C/C++ & GO )

华为OD机考双机位C卷 - 补种未成活胡杨(OD上机考试双机位C卷)。提供在线OJ刷题。Java、C++、Python、GO语言、C语言、JavaScript题解,并提供完整思路讲解。

算法大师! 2418

c++之vector

概述 vector是一个容器,可以存放变长数组,并且由使用者自己变化长度,解决了传统数组必须确定长度的问题。 vector使用一块连续的内存来存放元素,所以同样可以用指针来获取元素。 当在原有vector数组中添加新的元素,需要增加数组长度,但是因为vector使用了一种变长分配数组,所以不需要像普通数组一样开一个新数组,然后把原数组拷贝过去。优秀! vector容器一般会在声明一个数组以后分配...

sprite_Yang的博客 1133

基于PINN求解裂纹扩展问题的优化开发

本文提出了一种基于物理信息神经网络(PINN)的裂纹扩展问题求解方法。通过将线弹性断裂力学控制方程和裂纹尖端场特性嵌入神经网络损失函数,PINN有效克服了传统有限元法在处理裂纹扩展时面临的网格重构困难、计算成本高等问题。文章详细介绍了PINN网络架构设计、裂纹尖端奇异场处理、损失函数构造以及优化策略等关键技术。数值实验表明,该方法能准确预测裂纹扩展路径和应力强度因子,且在处理复杂几何和动态扩展问题时展现出显著优势。相比传统方法,PINN具有无网格、并行计算友好等特点,为断裂力学问题提供了新的求解范式。

huanghm88的专栏 152

C++ | string用法指南

本文主要介绍STL容器之一 ---- string,在学习C++的过程中,我们要将C++视为一个语言联邦(摘录于Effective C++ 条款一)。如何理解这句话呢,我们学习C++,可将其分为四个板块;分别为C、Object-Oriented C++(面向对象的C++)、Template C++(模板)、STL。本文就介绍STL中的string;

Nice_W的博客 2万+

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【C++】string的使用

讲解了C++中string的常用接口,以及string头文件中一些常见函数的使用,学会提前拓宽容量优化代码效率✨✨

Lin_Alpaca的博客 2792

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

从踩坑到封神:C++ string 类的构造、迭代器与容量管理终极指南(一)

本文介绍了C++标准模板库(STL)中的核心组件及其功能,重点讲解了string类的基本用法。STL包含容器、算法、迭代器等六大组件,其中string作为封装完善的字符串类,提供了丰富的操作方法。文章详细对比了四种字符类型(char/wchar_t/char16_t/char32_t)的特性及适用场景,并通过代码示例展示了string的多种构造函数,包括无参构造、拷贝构造和范围拷贝构造等。string类的引入解决了C语言字符串处理的局限性,使字符串操作更安全便捷。

分享 AI 时代程序员的进阶之路:大模型应用、AI 编程工具实战,同时沉淀 C / Linux 底层技术笔记。与君共赴,万里征途。 970

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Cpp::STL—string类的使用与理解(上)(8)

C语言中,字符串是以’\0’结尾的一些字符的集合(C-string),为了操作方便,C标准库中提供了一些 str 系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。这就是我们为什么学习string类的理由,如果你对前面类和对象的内容了解透彻的话,学习STL按道理来说应该不算太难。

tan180°的博客 1273

C++ string 从入门到精通:构造、迭代器、容量接口全解析

本文深入讲解了C++ STL中string类的核心语法与应用。首先介绍了string类存在的必要性,相比C风格字符串更安全高效。详细解析了string的默认成员函数、多种遍历方法(迭代器、范围for等)、容量管理接口(resize/reserve等)以及字符访问接口(at/back/front)。特别强调了VS和Linux下不同的扩容机制,以及C++11新增的auto和范围for语法。既包含基础用法也涵盖底层实现原理,是学习C++字符串处理的实用指南。

沫漓的博客 575

C/C++相关概念和易错知识点(34)(初始化注意事项、vector、编译器向上查找规则)

string可以一次性加入一个串,而vector只能单独加字符,string不管怎么操作,数据最后一定有个\0,而vector尾插不会有这个功能,需要自己去处理\0的情况,很不方便。图1展开命名空间的语句在展开头文件的下面,因此在向上查找的情况下,并不会读取using namespace std,也就不会在std命名空间里找,所以找不到。因此我们可知,string是专门针对字符数组的需求设计的,而vector是广泛适应的,vector不能替代string,需要根据不同的场景有不同的选择。

SGlow0708的博客 1103

C++ —— string类(上)

string严格来说是属于C++标准库的,不是属于STL(标准模板库)。我们看到里面其实是没有string的,string产生的比STL较早的,在头文件中,会单独看到一个string的头文件。C++文档所谓的string其实就是一个字符串 ,它要解决的就是要管理字符串。(日常当中字符串是很多的,如:身份证号码,家庭地址,电话号码等等)打开string头文件可以看到:有4种,这个与所谓的编码有关系,这里我们先看string://原生类型除了char,还有其他字符的类型(编码的原因)//原生类型。

2301_80873544的博客 1369

【C++】STL学习之string的使用

STL是C++伪函数空间配置器算法容器迭代器和配接器,其中各种各样的容器可以很好的辅助我们写程序,比如今天要介绍的string,有了它之后,我们对字符串的操作就能变得行云流水注意: string诞生于STL之前,因此存在部分接口冗余的情况。

Aron的博客 2268

【C++指南】string(一):string从入门到掌握

字符串处理无疑是一项极为基础且频繁的操作,从简单的文本输入输出,到复杂的文本分析与处理,字符串贯穿于程序的各个角落。 而 C++ 中的string类型,作为处理字符串的核心工具,为开发者提供了一种高效、便捷且安全的方式来操作字符序列。 本文将深入探讨 C++ 中string的奥秘,从其产生的根源basic_string模板类开始,逐步介绍std::string、wstring、u16string和u32string等相关类型,揭示它们之间的关系,以及它们与std库的紧密联系,并对basic_string

倔强的石头的博客 3286

C++ STL 学习之【string的使用】

STL 是 C++ 的重要组成部分,由六大部分构成:`伪函数`、`空间配置器`、`算法`、`容器`、`迭代器` 和 `配接器`,其中各种各样的 `容器` 可以很好的辅助我们写程序,比如今天要介绍的 `string`,有了它之后,我们对字符串的操作就能变得行云流水

北 海的博客 1760

【C++】简述STL——string类的使用

string类的使用

f_2789889770的博客 1440

C++ | string详解

其中提一下第三种,pos为子串的位置,len子串的长度,若len大于从子串pos位置开始后面字符总数,则表示初始化到子串结尾即可,比如我们要用 “hello world” 初始化字符串,若pos为6,len为20,则用world初始化字符串s1;由于各国语言的差异,可能存在一个字节不能够一一对应文字的情况,不像英文由26个英文字母组成单词,只需保存26个字母即可,而实际上许多国家的语言并不能由一字节的空间能表示出来,因此由不同储存方式繁衍出了 UTF-8、UTF-16、UTF-32,其中数字代码比特位;

GRL8013的博客 686

C++STL系列之string

string的使用

weixin_62188419的博客 874
上一篇: C/C++相关概念和易错知识点(31)(npos、string的基本使用)
下一篇: C/C++相关概念和易错知识点(33)(string的模拟实现)
-SGlow-
博客等级 码龄3年 1513粉丝 118原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值