一. 为什么学习string类?
1.1 C语言中的字符串
C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
二. 标准库中的string类
在使用string类时,必须包含#include头文件以及using namespace std;
2.1 auto关键字和范围for








for (auto* e : a)
会出错,这是因为 a
是一个整数数组,并非指针数组。for (auto* e : a)
尝试把数组元素当成指针来处理,然而整数并不能隐式转换为指针,所以会产生编译错误。你可以直接使用范围 for
循环遍历数组元素,或者使用传统的 for
循环配合指针来遍历。
2.2 string类的常用接口说明(注意下面我只讲解最常用的接口)
2.2.1. string类对象的常见构造
第一个就是无参构造,第二个就是通过给的一个字符串来构造我们的目标字符串的,第三个就是用几个那个字符来构造的字符串,第四个就是通过一个已经存在的对象拷贝给我们的目标字符串,我们来用一下吧。
我们来看一下,第一个就是无参构造,s2是通过给定一个字符串来初始化自己,第三个就是通过拷贝构造来初始化,第四个就是通过5个c初始化s4.
无参构造默认为/0,不打印。
相信大家可能有疑问string(const char* s)和string(const string&s)有什么区别呢?
第一个就相当于我们类的有一个参数的构造函数,而第二个就相当于是拷贝构造。
再介绍几个常用的吧。
我们看一下这个,s1表示是通过s3的第五个字符到第十个字符初始化自己。
s2表示从s3的第六个到最后一个字符来初始化自己,这些都是很常用的。
这是我们的运行结果。
2.2.2 string类对象的容量操作


reserve()
函数会让 std::vector
至少预留 new_cap
个元素的空间。若 new_cap
比当前的 capacity()
大,那么 std::vector
会重新分配内存,将容量扩充到至少 new_cap
;若 new_cap
小于等于当前的 capacity()
,则不会有任何操作。
2.2.3. string类对象的访问及遍历操作
相信大家看到上面的代码可能会有疑惑,为什么字符串也可以用[]的运算符呢?
这是因为底层实现了这个操作运算符的重载。
大概的实现过程就如上图所示,底层还是指针的解引用操作实现了这个功能。
在字符串中虽然最后是以/0结尾的,但是/0是不会影响字符串的大小的。
const修饰的字符串也是不能修改的。
修改就会报错了。
下面我们将讲一个东西叫做迭代器,它是string类中的一个工具,很实用。
通过类域找到迭代器,定义一个迭代器的对象,begin返回的是字符串的第一个字符的位置
,end返回的是最后一个字符的下一个位置。
就是这个样子。
我们刚才写了,s2是我们的const修饰的,我们要是还用普通的迭代器,就会出现权限被放大的情况了,因为你的s2.begin()返回的是const 类型的,而我们的迭代器接收的是非const类型的,权限被放大了,此时我们就要调用它对应的迭代器了。
这就是我们const修饰string类型所使用的迭代器了。
就是这个样子,它会优先调用最适合自己的函数,函数返回值加上const表示我们的返回值无法 被修改,函数后面加上const则表示
如果我们想从后往前来遍历字符串,我们该怎么办呢?
此时,迭代器就提供了一个很好的方法
我们用上图的迭代器就可以实现了。
为什么我们++,它会往前走呢?这里就用到了++运算符的重载了。
我们发现上面的类型都是很长了,此时我们就可以使用auto关键字了,是非常简便的。
三.结束语
感谢大家的查看,希望可以帮助到大家,做的不是太好还请见谅,其中有什么不懂的可以留言询问,我都会一一回答。 感谢大家的一键三连。