learn C++ NO.9——string(2)

news2024/11/24 6:49:41

引言:

现在是北京时间的2023年6月15日早上的10点14分。时间过得飞快,现在已经大一的最后一个星期了。明天也是大一最后一次课,线下的实训课。线下实训内容为c语言二级的内容,对我来说跟学校的课效率太低下了,我还是比较喜欢按自己的节奏来,一般我是直接带笔记本过去按自己计划学习。可能大多数的同学还是意识不到在人生的无限博弈中,持续学习的重要性吧,兴许今天大家都是在同一个教室里,但是,三年后也许大家的人生就会步入不一样的道路。当然,也恳请看到本篇文章的你,不要放弃学习这则有较大概率改变人生的选项!
在这里插入图片描述

文章目录

  • 引言:
  • operator[]重载
  • 迭代器的介绍
    • 迭代器与范围for
    • 迭代器跟算法配合
    • 反向迭代器
  • 容量相关的成员函数

operator[]重载

string因为支持了下标访问操作符重载,使得访问string实例化生成的对象可以像访问字符数组那样直接使用下标访问操作符进行指定编译量的访问以及修改。下面简单演示一下string的下标访问操作符的运算符重载。

#include<iostream>

using namespace std;

int main()
{
	string s1("hello world");
	char s2[] = "hello world";
	
	cout << s2 << endl;

	for (size_t i = 0; i < s1.size(); i++)
	{
		s1[i]++;//通过下标进行修改
	}

	s1[0]--;

	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1[i];//进行打印
	}
	cout << endl;

	
	s1[1]++;//(s1.operator[](1))++
	s2[1]++;//->(*(s2+1))++

	return 0;
}

在这里插入图片描述
虽然两者在使用时是类似的,但这也并不意味着string类对象和char类型字符数组在底层实现上是一样的。string类对象使用下标访问操作符时,编译器会去调用它的运算符重载函数,而字符数组在使用下标访问操作符时,编译器根据数组首元素地址去进行解引用操作来访问。
在这里插入图片描述

迭代器的介绍

迭代器(iterator)是一种用于遍历数据集合的对象,可以按照一定顺序依次访问数据中的元素,而无需了解底层数据结构的实现方式。迭代器适用于各种不同类型的数据结构,包括数组、链表、树等等,并且支持可自定义的遍历顺序,例如前序、中序、后序等访问方式。迭代器的使用可以简化代码的编写,提高代码的可读性和可维护性。下面就简单介绍一下string类对象是如何用迭代器的。
在正式介绍迭代器之前,先介绍两个与迭代器相关的函数,begin()和end()。老规矩我们还是先查看文档,begin()函数返回的是指向string类对象第一个元素的迭代器。end()函数返回的是指向string类对象’\0’前元素的迭代器。
在这里插入图片描述

#include<iostream>

using namespace std;

int main()
{
	string s1("hello world");

	//迭代器简单用法
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		(*it)++;//修改数据
		it++;
	}

	it = s1.begin();
	while (it != s1.end())
	{
		cout << *it;//打印数据
		it++;
	}
	cout << endl;
	return 0;
}

这里我们可以把迭代器简单理解成指针,当然这并不代表所有迭代器都是指针。这里在后面学习中我们会给大家再做介绍。迭代器给我们提供了另一种访问string类容器的方法。由于我们前面在学习c语言的时,最先接触到的访问字符数组的方法使用下标访问操作符进行访问,这也导致了我们会觉得iterator可能用起来并没有那么香。事实上并非如此,因为STL容器中是否都支持下标访问呢?答案并不是所有容器都支持下标访问,比如链表、树形结构、图等都不支持下标访问。但是,它们都支持迭代器进行遍历访问。这也是我们要学习迭代器的原因。下面我就照猫画虎,简单演示下interator遍历别的容器。
在这里插入图片描述

迭代器与范围for

在前面初始c++一文中,介绍了c++11的一个语法糖范围for。那么相信你可能就好奇了,范围for跟迭代器有什么关系呢?当然有关系了。因为范围for底层实现其实就是依靠的迭代器。

int main()
{
	string s1("hello world");

	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it;//打印数据
		it++;
	}
	cout << endl;

	for (auto& e : s1)
	{
		cout << e;
	}
	cout << endl;

	return 0;
}

在这里插入图片描述

迭代器跟算法配合

在类和对象的学习中,我们不难发现c++的类通常都是将数据给私有化,那么我们想要操作那些容器的数据就得使用迭代器加算法进行操作。下面我就简单一个常用的算法并进行实例演示。
在这里插入图片描述

#include<iostream>
#include<string>
#include<algorithm>

using namespace std;

int main()
{
	string s1("hello world");

	string::iterator it = s1.begin();

	reverse(s1.begin(),s1.end());
	for (auto& e : s1)
	{
		cout<<e;
	}
	cout << endl;
	
	return 0;
}

在这里插入图片描述

反向迭代器

反向迭代器与上面介绍的正向迭代的用法是一致的。但是区别在于参数以及迭代器的名称不同。
在介绍对应的两个相关的成员函数rbeign()和rend()。rbegin()返回一个指向最后一个string类对象的元素的反向迭代器。rend()返回一个指向string类对象第一个元素的前一个位置的反向迭代器。
在这里插入图片描述
当然正向迭代器以及反向迭代器都是支持被const进行修饰的。const修饰迭代器后,迭代器的权限会被缩小,从支持读写到只读。下面就简单上两个案例。
在这里插入图片描述
在这里插入图片描述
auto自动类型推导还是非常香的,可以让类型的推导交给编译器来进行,极大程度的提升了我们写代码的效率。

容量相关的成员函数

在这里插入图片描述
size()和length()两个函数的功能是一样的,就是返回string类对象的长度,即’\0’前的元素个数。那为什么会有两个功能一样的函数呢?这是因为string类在一开始实现的时候,只提供了length接口。但是,随着后面STL标准库横空出世后,string类为了和STL标准库中的容器的用法不做差异,于是又提供了一个size()接口。这也是历史的原因。string类是比STL标准库更早出现的,严格来说string并不属于STL,而是属于c++标准库。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
max_size()接口其实不具备太大的意义,因为max_size()接口在不同的平台下的值其实是不同的,这也意味着它的跨平台性是较差的。虽然不同平台下的实现规范是一样的,但是实现的细节方面有所差异。
在这里插入图片描述

在这里插入图片描述
下面我们来看看capacity()接口。capacity接口因为不同的平台下的的实现扩容逻辑有所差异,所以在不同平台下的值也是不同的。
在这里插入图片描述

在这里插入图片描述
clear()接口,就是将string类对象的内容清空,也就是将数据插入的下标位置给置成0。当然,调用clear()接口并不影响string类的容量。
在这里插入图片描述

在这里插入图片描述
string的reserve()函数用于为字符串预留空间,以减少需要动态分配内存的次数,提高字符串操作的效率。调用reserve()函数后,字符串对象的容量将至少为指定的参数值,但不会改变字符串的长度(即字符串中字符的数量),也不会初始化新增的容量部分。如果在字符串中添加大量字符概会需要的容量大小,可以使用reserve()函数来避免频繁的重新分配内存造成的开销。注意,使用reserve()函数过度也可能导致浪费内存,因此应该根据实际情况选择合适的调用时机和参数值。
在这里插入图片描述
在这里插入图片描述
下面简单resize()接口,resize接口可以将string类对象的size(即元素有效个数)调整到n。也支持指定字符来初始化调整的空间。当你缩小size时,会默认给默认值赋予string类对象,这个默认的字符值为’\0’。下面简单演示一下。
在这里插入图片描述
在这里插入图片描述
根据对上面的string类capacity相关的成员函数的认识后,我们可以发现,其实string类实现的底层对于string类对象的容量几乎是不会涉及到缩容的。当然也介绍了一个特殊例子(clear后,可能会采取缩容)。根据我们前面对于c/c++内存管理的所学知识,可以大致分析出这是因为系统底层缩容的逻辑并不是向我们想象中的,可以一部分一部分的讲内存还给操作系统。而是还给操作系统就必须全部还给操作系统。这样导致了缩容必须先将一部分数据拷贝到开辟的新空间后,在讲原空间还给操作系统。这样对于程序的性能会有损耗,在内存成本日益降低的现在,这样的行为也显得并不值当了。
在这里插入图片描述

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

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

相关文章

初识网络之再看udp协议

目录 一、端口号 1. 五元组 2. 端口号范围划分 3. 一些知名端口号 4. 进程与端口号 5. 两个常用网络工具 5.1 netstat 5.2 pidof 二、UDP协议 1. udp协议格式 2. udp报文解包 3. udp报文分用 4. udp的特点 5. 缓冲区 5.1 tcp缓冲区 5.2 udp缓冲区 6. 一些常见…

函数重载异常的常见原因

函数重载异常的常见原因 使用重载函数时&#xff0c;如果数据类型不匹配&#xff0c;C尝试使用类型转换与形参进行匹配&#xff0c;如果转换后有多个函数能匹配上&#xff0c;编译将报错。引用可以作为函数重载的条件&#xff0c;但是&#xff0c;调用重载函数的时候&#xff0…

Linux:端口

端口是设备与外界进行通讯的出入口&#xff0c;端口可以分为物理端口和虚拟端口 物理端口&#xff1a;又叫接口&#xff0c;是可见的端口&#xff0c;比如HDMI端口、USB接口虚拟端口&#xff1a;是指计算机内部的端口&#xff0c;用来操作系统和外部进行交互使用 通过IP地址只能…

6.python高频函数-处理缺失值isnull()、fillna()、dropna()

前言 如何判断pandas.DataFrame、Series是否包含缺失值NaN以及如何处理缺失值NaN。 Part.1 isnull() 函数 使用 isnull()、isna() 确定每个元素的缺失值 如果值为 NaN&#xff0c;则值为 True&#xff0c;如果不是&#xff0c;则值为 False。 读取数据集 panel_data pd.r…

从C语言到C++_19(容器适配器+stack和queue模拟实现+优先级队列priority_queue)

目录 1. 容器适配器 1.1 什么是适配器 1.2 STL标准库中stack和queue的底层结构 2. stack和queue的模拟实现 2.1 stack模拟实现 2.2 queue的模拟实现 3. deque的介绍(了解) 3.1 deque的实现原理 3.2 deque的缺陷和使用场景 4. 优先级队列 priority_queue 4.1 priorit…

编码规范、Git分支整理

代码命名规范 包命名规范 采用反域名命名规则&#xff0c;全部使用小写字母。一级包名为com&#xff0c;二级包名kl&#xff08;为公司名称&#xff0c;可以简写&#xff09;&#xff0c;三级包名pos&#xff08;根据应用进行命名&#xff09;&#xff0c;四级包名activity或…

芳禾数据CTO李明:数据分类分级与治理驱动下的应用革命丨数据猿专访

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 我们进入数字化时代&#xff0c;数据已经变得比任何时候都更加关键。每天&#xff0c;我们都在生成、处理和存储海量的数据&#xff0c;这些数据在企业决策、市场研究、产品开发等方面扮演着重要的角色。然而&#xff0c;数…

Qt编写精美输入法(历时十年迭代/可换肤/支持Qt4/5/6/win/linux/mac/嵌入式等)

一、前言 大概是从2012年就开始研究用Qt写输入法&#xff0c;因为项目需要&#xff0c;嵌入式板子上&#xff0c;没有对应的输入法&#xff0c;当初使用过很多NVR&#xff0c;里面也是鼠标按下弹出输入法面板进行输入&#xff0c;可以切换数字和字母及中文&#xff0c;于是借鉴…

5大趋势与10大应用场景!未来的智能工厂要这么建...

在经济下行压力、人口红利消失、消费结构升级、疫情冲击等多种因素推动下&#xff0c;制造企业加快转型步伐&#xff0c;工厂正向高效化、智能化、绿色化方向跃迁升级&#xff0c;不断涌现出技术创新、应用领先、成效显著的智能工厂。 近日&#xff0c;中国信息通信研究院发布…

常见的台账在线、可视化数据看板工具

目前已知和常见的一些在线可视化数据看板工具&#xff1a; Trello&#xff1a;Trello 是一种流行且直观的看板工具&#xff0c;可让创建看板、列表和卡片来管理任务和项目。它提供了一个可视化界面&#xff0c;可以在其中跨工作流程的不同阶段拖放卡片。还可以添加截止日期、标…

cesium调用celestrak接口获取卫星数据

celestrak是一家免费开源提供卫星空间数据的非营利性组织 接口调用 import axios from "axios";const BASE_URL "https://celestrak.org";function getTleDataFromExternal(path "") {let uri ${BASE_URL}/NORAD/elements/gp.php?GROUP${…

复习并发编程的基础知识之线程池

并发编程中&#xff0c;线程池是很重要的一块内容。 线程池是一种池化技术&#xff0c;线程池、字符串常量池和数据库链接池都属于池化技术。 使用线程池的好处&#xff1a; 1.提高了线程的利用率&#xff08;想一想&#xff0c;我们不可能每打一个电话&#xff0c;就去买一部手…

Unity编辑器扩展-第三集-添加按钮到组件菜单并且重置组件

第二集链接&#xff1a;Unity编辑器扩展-第二集-按钮排序/分组/放入右键菜单_菌菌巧乐兹的博客-CSDN博客 一、本节目标效果展示 1.把按钮放到组件菜单上 2.做一个类似Reset功能&#xff0c;点一下能改变里面的数据 二、 把按钮放到组件菜单上 如上图&#xff0c;我的的组件名…

echarts 配置相关

echarts更多模板链接 http://chart.majh.top/ 1、echarts.clear()是清空当前实例&#xff0c;会移除实例中所有的组件和图表。 echarts.dispose()是销毁实例&#xff0c;销毁后实例无法再被使用。 this.chart.dispose() this.chart.clear(); // 清空图表2、series虽然是[] 数…

BRC20赛道的刚需基础设施,BrccSwap如何延续新的造富神话?

引言 BRC20代币和去中心化交易所的背景 BRC20代币赛道的刚需SWAP BrccSwap如何延续新的造富神话 结语 引言 随着加密货币市场的不断发展&#xff0c;BRC20代币和去中心化交易所成为了越来越受欢迎的概念。BRC20代币是建立在比特币区块链上的代币&#xff0c;具有高级别的…

一季度亏损47亿,全系降价背后,蔚来能否实现自救?

降价之后&#xff0c;蔚来能否实现自救&#xff1f; 6月12日&#xff0c;蔚来汽车宣布全系车型起售价减 3 万元&#xff1b;新购车首任车主用车权益调整为整车6年或15万公里质保等&#xff1b;免费换电补能不再作为标准用车权益&#xff0c;新用户可灵活选择在家充电或到充换电…

new Vue后整个的流程

文章目录 new Vue后整个的流程Vue.js 创建应用程序流程概述使用 new Vue() 创建Vue 实例流程概述 new Vue后整个的流程 new Vue({el: #app,render: h > h(App),data() {return {message: hello vue}} }).$mount(#app)Vue.js 创建应用程序流程概述 在使用 Vue.js 创建一个应…

Linux:进程管理

进程&#xff1a;为管理程序的运行&#xff0c;操作系统会给每个运行的程序都注册为系统的一个进程&#xff0c;并为每个进程分配一个进程id 查看进程&#xff1a;Linux中可以通过ps命令查看系统中的进程信息&#xff0c;语法&#xff1a; ps [-e -f] -e选项&#xff1a;表示显…

0基础入门---第3章---神经网络(前向传播)

&#x1f31e;欢迎来到深度学习的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f64f;作者水平很有限&#xff0c;如果发现错误&#xff…

退出印度之后,越南制造也有麻烦,苹果摆脱中国制造成幻想

日前媒体报道指苹果在越南的代工厂面临麻烦&#xff0c;由于越南缺乏足够的电力供应&#xff0c;越南的工厂出现断电的问题&#xff0c;工厂生产被迫暂停&#xff0c;最严重的时候连续20天白天无法开工&#xff0c;这对于苹果来说无疑是又一个重大打击。 一、苹果的印度制造计划…