您现在的位置是:首页 >学无止境 >【C++】string类的深入介绍网站首页学无止境

【C++】string类的深入介绍

爱写代码的刚子 2024-10-18 12:01:03
简介【C++】string类的深入介绍

【C++】string类的深入介绍(1)

作者:爱写代码的刚子
时间:2023.5.26
本篇博客主要深入介绍string类、string类的常用接口及操作,string中迭代器的使用,以及string中的部分方法。(由于篇幅有限,剩余方法以及string的深浅拷贝将在之后的博客介绍)
前言:C语言中,字符串是以’’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

C++参考网站:

C++参考
C++官网
如果方便地查找网页中的关键字可以使用ctrl + f进行搜索
以C++参考网站为例,演示查找string类:
在这里插入图片描述

标准库中的string类

string类(了解即可)
  1. 字符串是表示字符序列的类
  2. 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作
    单字节字符字符串的设计特性。
  3. string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信
    息,请参阅basic_string)。
  4. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits
    和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。
  5. 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

总结:

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
  4. 不能操作多字节或者变长字符的序列。
  • 在使用string类时,必须包含#include头文件以及using namespace std;
string类的常用接口说明(最常用的)

学会查文档对C++的学习是非常重要的!(以下使用参考网站为例):
在这里插入图片描述
这里只列举的部分,大家学习的时候一定要学会查文档!

  • string类对象的常见构造
(constructor)函数名称功能说明
string()(重点)构造空的string类对象,即空字符串
string(const char* s)(重点)用C-string来构造string类对象
string(size_t n,char c)string类对象中包含n个字符c
string(const string&s)(重点)拷贝构造函数
  • string类对象的容量操作
函数名称功能说明
size(重点)返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty(重点)检测字符串释放为空串,是返回true,否则返回false
clear(重点)清空有效字符
reserve(重点)为字符串预留空间
resize(重点)将有效字符的个数改成n个,多出的空间用字符c填充

注意:

  1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一
    致,一般情况下基本都是用size()
  2. clear()只是将string中有效字符清空,不改变底层空间大小。
  3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
  4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于
    string的底层空间总大小时,reserver不会改变容量大小。
  • string类对象的访问及遍历操作
函数名称功能说明
operator(重点)返回pos位置的字符,const string类对象调用
begin + endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rendrbegin返回一个逆向迭代器,指向字符串的最后一个字符+rend返回一个逆向迭代器,指向字符串的开头(第一个字符的前一个位置)。
范围forC++11支持更简洁的范围for的新遍历方式
  • string类对象的修改操作
函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+=(重点)在字符串后追加字符串str
c_str(重点)返回C格式字符串
find + npos(重点)从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

注意:

  1. 在string尾部追加字符时,s.push_back© / s.append(1, c) / s += 'c’三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
  • string类非成员函数
函数功能说明
operator+尽量少用,因为传值返回,导致深拷贝效率低
operator>>(重点)输入运算符重载
operator<<(重点)输出运算符重载
getline(重点)获取一行字符串
relational operators(重点)大小比较

在这里插入图片描述

  • 需要注意的一个小点:
    在对string类使用<<的运算符重载进行比较时,我们一定要注意==<<的优先级较高(相较于普通的运算符)==,所有我们进行比较时要带上括号!
    在这里插入图片描述

  • 正确使用:
    在这里插入图片描述

    • npos静态变量的介绍:

在这里插入图片描述
npos不是-1,而是整形的最大值(因为npos是无符号整型)
在这里插入图片描述

  • 其他一些重要的修饰符和字符串操作:
    在这里插入图片描述
    append(追加字符串)以及push_back(尾插一个字符)等一些函数已经实现了自动扩容(C++的好处,本质是字符管理的顺序表),但是建议使用 += ,因为 += 重载了这两种方法(例:string str;str += ('0' + val);(直接将整型val转成字符串))
    注意有些情况+=不能替代append
    下面是append具体信息:
    在这里插入图片描述

具体用法查文档即可

详细介绍string::operator[]

示例:
在这里插入图片描述

上述代码中str和a虽然都是字符串,但是str的实现逻辑是调用string::operator,而a的实现逻辑是*(a+1);(在clion编译器中编译器跳过了第9行的a[1];语句,没有执行(编译器的优化))

迭代器

string中的迭代器(任何容器都支持,用法都是类似的)

示例:
在这里插入图片描述

  • iterator是像指针一样的类型,有可能是指针,有可能不是指针(封装的指针)。(其实iterator的底层是用指针来实现的)
  • 范围for(底层替换为迭代器,可以查看反汇编代码,一个类支持迭代器就支持范围for)
    在这里插入图片描述

以上代码中若要进行对str2的修改可以使用引用:
在这里插入图片描述

  • 链表中使用迭代器
    在这里插入图片描述
    iterator提供了一种统一的方式,访问和修改容器的数据。算法通过迭代器去处理容器中的数据
  • 迭代器可以和容器进行配合
    以reverse函数举例:
    在这里插入图片描述
    由于reverse提供了list模版,所以可以对链表实现逆置。
    当然,也可以使用范围for来替代迭代器:
    在这里插入图片描述
string中的反向迭代器

在这里插入图片描述
而范围for不能反向遍历

begin()、end()以及rbegin()、rend()具体指向的位置

如下图所示
在这里插入图片描述

const迭代器

注意auto在自动识别类型时并不带上常量属性
在这里插入图片描述

  • 如果我们想要使迭代器带上常量属性需要加上const_
    在这里插入图片描述
    此时使用迭代器时不能改变存储在容器中的数据。
    附:其他迭代器补充:
    在这里插入图片描述
    可以去作者提供的C++参考网站上去查询函数的具体用法(建议多查找网站)

string中的Capacity

在这里插入图片描述

  • string类中有两种表示字符串长度的方法(size()和length()),这里只推荐使用size(),因为有些STL不支持length()(比如map)
max_size

max_size在不同的编译器上的结果不同。(所以使用时需谨慎,因为STL只是规范,它有许多不同的版本(大同小异),导致结果不同)
演示:
clion下:
在这里插入图片描述

  • Linux下:
    在这里插入图片描述
capacity

同max_size,在不同的编译器下的结果并不相同!
clion下:
在这里插入图片描述
Linux下:
在这里插入图片描述
同时不同的编译器的扩容机制也不相同
演示:
clion下:
在这里插入图片描述

Linux下:
在这里插入图片描述

clear(清理空间但并不释放空间

clion下:
在这里插入图片描述
Linux下:
在这里插入图片描述
所以clear()并不会释放空间

reserve(提前给string开空间)

在这里插入图片描述
clion下:
clion即使清理了数据,也不会进行缩容
在这里插入图片描述

Linux下:
如果清理了数据使用reserve就会进行缩容,缩为0
在这里插入图片描述
如果没有清理数据也进行缩容,缩小到size大小
在这里插入图片描述

不同的编译器reserve的效果不同,同时还与clear函数有关,clion下没实现缩容,而Linux的g++编译器下会实现缩容(使用clear清理数据后会缩到0,如果没有清理数据则会缩小到size大小)。

resize 不单单扩容,而是开空间加初始化(不给初始化值默认/0)

在这里插入图片描述
resize如果给的值比原来string的size小,并不会缩容,capacity不会改变,空间没销毁,但是字符串的长度改变了 因为缩容是有代价的,所以resize不会改变空间,以免之后还要开空间

  • 如果想要实现缩容可以用shrink_to_fit函数(具体用法查网站即可),但不建议缩容。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。