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

这篇具有很好参考价值的文章主要介绍了learn C++ NO.9——string(2)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言:

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

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;
}

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

迭代器的介绍

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

#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遍历别的容器。
learn C++ NO.9——string(2)

迭代器与范围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;
}

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

迭代器跟算法配合

在类和对象的学习中,我们不难发现c++的类通常都是将数据给私有化,那么我们想要操作那些容器的数据就得使用迭代器加算法进行操作。下面我就简单一个常用的算法并进行实例演示。
learn C++ NO.9——string(2)

#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;
}

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

反向迭代器

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

容量相关的成员函数

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

learn C++ NO.9——string(2)
max_size()接口其实不具备太大的意义,因为max_size()接口在不同的平台下的值其实是不同的,这也意味着它的跨平台性是较差的。虽然不同平台下的实现规范是一样的,但是实现的细节方面有所差异。
learn C++ NO.9——string(2)

learn C++ NO.9——string(2)
下面我们来看看capacity()接口。capacity接口因为不同的平台下的的实现扩容逻辑有所差异,所以在不同平台下的值也是不同的。
learn C++ NO.9——string(2)

learn C++ NO.9——string(2)
clear()接口,就是将string类对象的内容清空,也就是将数据插入的下标位置给置成0。当然,调用clear()接口并不影响string类的容量。
learn C++ NO.9——string(2)

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

到了这里,关于learn C++ NO.9——string(2)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++学习 Day15(string类)

    C 语言中,字符串是以 \\\'\\0\\\' 结尾的一些字符的集合,为了操作方便, C 标准库中提供了一些 str 系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP 的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。 在 OJ 中,有关字符串的题目基本以 stri

    2024年02月08日
    浏览(41)
  • Learning C++ No.31 【线程库实战】

    北京时间:2023/6/11/14:40,实训课中,实训场地有空调,除了凳子坐着不舒服之外,其它条件都挺好,主要是我带上了我自己的小键盘,并且教室可以充电,哈哈哈,巴士!老师还是非常善解人意滴,并没有强迫我们听她讲C语言二级相关知识,虽然这种实训本质就是在刷题式教

    2024年02月08日
    浏览(40)
  • Learning C++ No.26 【深入学习位图】

    北京时间:2023/5/30/15:30,刚睡醒,两点的闹钟,硬是睡到了2点40,那种睡不醒的感觉,真的很难受,但是没办法,欠的课越来越多,压的我喘不过气了都,早上把有关unordered_set和unordered_map的内容给写完了,所以哈希表有关代码方面的知识,我们就搞定的差不多了,并且现在

    2024年02月07日
    浏览(39)
  • learn C++ NO.4 ——类和对象(2)

    在 C++ 中,如果没有显式定义类的构造函数、析构函数、拷贝构造函数和赋值运算符重载函数,编译器会自动生成这些函数,这些函数被称为默认成员函数。 初步了解了默认成员函数,上面的空类Date,其实在程序运行时,编译器会默认生成它的默认成员函数。 小结 当没有显

    2024年02月05日
    浏览(33)
  • learn C++ NO.6——类和对象(4)

    1.1.构造函数体赋值 在创建类的对象时,编译器回去调用类的构造函数,来各个成员变量一个合适的值。 虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。

    2024年02月06日
    浏览(33)
  • Learning C++ No.21 【AVL树实战】

    北京时间:2023/5/13/10:13,饥肠辘辘,为了将红黑树的博客赶出来,导致现在还没有吃早饭,所以现在先容我去吃一下早饭,ok,转眼一看,12:25,哈哈哈,时间过的真快啊,那是因为我吃完早饭,实在是忍不住摆烂,去睡了一觉,睡到刚刚,应该不是自然醒,算是给热醒的,哈

    2024年02月05日
    浏览(40)
  • Learning C++ No.29 【右值引用实战】

    北京时间:2023/6/7/9:39,上午有课,且今天是周三,承接之前博客,今天我又去帮我舍友签到早八,但愿这次不会被发现吧!嘻嘻嘻!并且刚刚发文有关对C++11相关知识,由于所剩时间不多,这里我们就简单的为下篇博客,当然也就是该篇博客打一打铺垫,哦!对了,今天是高

    2024年02月08日
    浏览(45)
  • Learning C++ No.24 【哈希/散列实战】

    北京时间:2023/5/20/7:30,周六,可惜有课,而且还是早八,说明我们现在没有多少的学习时间啦!得抓紧把该博客的引言给写完,我们距离期末考越来越近啦!再过一个星期就要开始停课,然后进行什么实训,目前推测,这个实训估计就是在摆烂中摆烂,不过没有关系,只要

    2024年02月06日
    浏览(44)
  • Learning C++ No.20 【红黑树实战】

    北京时间:2023/5/12/20:30,今天周五,周五不摆烂从我做起,虽然刚睡醒,但是今天如果论学习时长,那可能是许久以来最长的一天,从早上6:40晨跑回来坐在凳子上,一坐久坐到了下午13:40,然后睡了10分钟去上了一节心理课,心理课结束去吃了个饭,回到宿舍16:20,帮同学下载

    2024年02月05日
    浏览(45)
  • Learning C++ No.28 【C++11语法实战】

    北京时间:2023/6/5/9:25,今天8点45分起床,一种怎么都睡不够的感觉,特别是周末,但是如果按照我以前的睡觉时间来看,妥妥的是多睡了好久好久,并且昨天也睡了一天,哈哈哈,睡觉这方面,真的睡能比我强,昨天是实训课,课程内容主要就是做一些C语言二级的题目,虽

    2024年02月08日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包