【C++】:string用法详解

news/2024/11/20 10:40:38/

朋友们、伙计们,我们又见面了,本期来给大家解读一下有关Linux的基础知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!

C 语 言 专 栏:C语言:从入门到精通

数据结构专栏:数据结构

个  人  主  页 :stackY、

C + + 专 栏   :C++

Linux 专 栏  :Linux

​ 

目录

1. 什么是STL

2. STL六大组件

3. 标准库中的string类

3.1string类

4. string类的常用接口

4.1string类对象的常见构造

4.2string类对象的容量操作

4.3string类对象的访问及遍历操作

4.4string类对象的修改操作

4.5string的非成员函数 

5. vs和g++下string结构的说明

5.1vs下的string结构

5.2g++下string结构


1. 什么是STL

STL(standard template libaray-标准模板库):是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

2. STL六大组件

3. 标准库中的string类

 string类的文档介绍

3.1string类

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; 

4. string类的常用接口

 关于string类中的接口有许多许多,在这里只介绍最常用的接口。

4.1string类对象的常见构造

string类构造的参考文档

string()
构造空的string类对象,即空字符串
string(const char* s)
用C-string来构造string类对象
string(size_t n, char c)
string类对象中包含n个字符c
string(const string&s)
拷贝构造函数
void Teststring()
{string s1;   //空字符串string s2("hello world!");  //字符串构造string s3(10, 'x'); //字符构造string s4(s2);  //拷贝构造s2
}

4.2string类对象的容量操作

size返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty 检测字符串是否为空串,是返回true,否则返回false
clear 清空有效字符
reserve 为字符串预留空间**
resize re将有效字符的个数改成n个,多出的空间用字符c填充

1. size、length、capacity、clear、empty

void Teststring_capacity1()
{string s("Hello World!!");//字符串的有效长度cout << s.size() << endl;  //这两个计算出来的结果都不包含'\0'cout << s.length() << endl;//s的容量cout << s.capacity() << endl;//判空cout << s.empty() << endl;//清理数据,但不释放空间s.clear();cout << s.empty() << endl;cout << s.capacity() << endl;
}

​​​​​​​

2. resize

void Teststring_capacity2()
{string s("Hello World!!");//1. 指定字符//多出来的空间用指定字符填充s.resize(20, 'x');cout << s << endl;//2. resize大小小于sizes.resize(11);cout << s.size() << endl;cout << s << endl;//3. resize大于size// 多出来的空间使用'\0'填充s.resize(20);cout << s.size() << endl;
}

3.  reserve 

void Teststring_capacity3()
{string s("xxx");cout << s.size() << endl;cout << s.capacity() << endl;//扩容的空间小于预留空间,则不会改变s.reserve(10);cout << s.size() << endl;cout << s.capacity() << endl;s.reserve(20);cout << s.size() << endl;cout << s.capacity() << endl;
}

总结:

  •  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 n = 0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

4.3string类对象的访问及遍历操作

operator[ ] 返回pos位置的字符,const string类对象调用
begin+ endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭
代器
rbegin + rendbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭
代器
范围forC++11支持更简洁的范围for的新遍历方式

1. operator[ ] 

void Teststring_access1()
{string s1("Hello World");string s2 = "Hello World!!!"; //遍历s1for (size_t i = 0; i < s1.size(); i++){//读cout << s1[i];}cout << endl;//遍历s2for (size_t i = 0; i < s2.size(); i++){//读cout << s2[i];}cout << endl;
}

2. 迭代器 和 begin+ end、rbegin + rend

void Teststring_access2()
{string s = "Hello World!";//正向迭代器string::iterator it = s.begin();//auto it = s.begin();  //使用auto自动识别类型while (it != s.end()){//读cout << *it;++it;}cout << endl;//反向迭代器string::reverse_iterator rit = s.rbegin();//auto rit = s.rbegin();  //使用auto自动识别类型while (rit != s.rend()){//读cout << *rit;++rit;}cout << endl;
}

迭代器默认是可以进行读和写

void Teststring_access3()
{string s = "Hello World!";//遍历for (size_t i = 0; i < s.size(); i++){//写s[i]++;cout << s[i];}cout << endl;//迭代器string::iterator it = s.begin();while (it != s.end()){//写*it = 'x';++it;}cout << s << endl;
}

3. 范围for

void Teststring_access4()
{string s = "Hello World!";// 原理:编译器编译器替换成迭代器//范围forfor (auto ch : s){//读cout << ch;}cout << endl;//范围forfor (auto& ch : s){//写ch++;}cout << s << endl;
}

4.4string类对象的修改操作

push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+= 在字符串后追加字符串str
c_str返回C格式字符串
find + npos从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

1. 头插、追加、尾删

void Test_modify1()
{string s;//尾插s.push_back('H');s.push_back('e');cout << s << endl;//追加s += "llo";s.append(" World!");cout << s << endl;//尾删删除s.pop_back();cout << s << endl;
}

2.c_str、npos、substr、find

void Test_modify2()
{string s = "Hello World!";//返回C格式的字符串cout << s.c_str() << endl;size_t pos = s.find('!');//s[pos]++;cout << s.c_str() << endl;cout << s.substr(2, 5) << endl;cout << s.substr() << endl;//不传参默认从头开始一直截取到尾
}

注意:
1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

4.5string的非成员函数 

函数功能说明
operator+尽量少用,因为传值返回,导致深拷贝效率低
operator>> 输入运算符重载
operator<< 输出运算符重载
getline 获取一行字符串
relational operators 大小比较

string非成员函数相关接口查看的文档

在string中是支持流插入和流提取,因为string中将<< 和 >>运算符重载了

void Test()
{string s;//输入cin >> s;//输出cout << s << endl;
}

getline可以获取一行的字符串,并不会因为遇到空格而停下来:

void Test2()
{string s;//输入getline(cin, s);cout << s << endl;
}

5. vs和g++下string结构的说明

注意:下述结构是在32位平台下进行验证,32位平台下指针占4个字节

5.1vs下的string结构

string总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字符串的存储空间:

  • 当字符串长度小于16时,使用内部固定的字符数组来存放
  • 当字符串长度大于等于16时,从堆上开辟空间
union _Bxty{ // storage for small buffer or pointer to larger onevalue_type _Buf[_BUF_SIZE];pointer _Ptr;char _Alias[_BUF_SIZE]; // to permit aliasing} _Bx;1 2 3 4 5 6

这种设计也是有一定道理的,大多数情况下字符串的长度都小于16,那string对象创建好之后,内部已经有了16个字符数组的固定空间,不需要通过堆创建,效率高。其次:还有一个size_t字段保存字符串长度,一个size_t字段保存从堆上开辟空间总的容量最后:还有一个指针做一些其他事情。


故总共占16+4+4+4=28个字节。

5.2g++下string结构

G++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指针将来指向一块堆空间,内部包含了如下字段:

  • 空间总大小
  • 字符串有效长度
  • 引用计数
struct _Rep_base
{size_type      _M_length;size_type      _M_capacity;_Atomic_word   _M_refcount;
};
  • 指向堆空间的指针,用来存储字符串

 

朋友们、伙计们,美好的时光总是短暂的,我们本期的的分享就到此结束,欲知后事如何,请听下回分解~,最后看完别忘了留下你们弥足珍贵的三连喔,感谢大家的支持!


http://www.ppmy.cn/news/1158389.html

相关文章

windows每天定时重启 Win11 Win10定时重启 windows定时重启系统 windows每天定时重启

windows每天定时重启 Win11 Win10定时重启 windows定时重启系统 windows每天定时重启 使用 Windows 的任务计划程序来设置每天自动重启计算机1. 打开 任务计划程序&#xff1a;2. 在 任务计划程序库 面板中&#xff0c;创建一个基本任务3、设置计划任务权限 使用 Windows 的任务…

【网络编程】序列化与反序列化

文章目录 一、网络协议二、序列化和反序列化1. 结构化数据2. 序列化和反序列化 三、网络版计算器1. 协议定制2. 客户端处理收到的数据3. 整体代码 一、网络协议 网络协议 是通信计算机双方必须共同遵从的一组约定&#xff0c;为了使数据在网络上能够从源地址到目的地址&#x…

Notes/Domino 14 Early Access Drop3发布

大家好&#xff0c;才是真的好。 其实上周&#xff0c;就是国庆假期的时候&#xff0c;HCL Notes/Domino 14 Early Access Drop3&#xff08;以下简称EA3&#xff09;就已经发布&#xff0c;而且和传说中的一样&#xff0c;带来了数项惊人的新特性。 我们先讲讲这一版本新特性…

分类算法-逻辑回归与二分类

1、逻辑回归的应用场景 广告点击率是否为垃圾邮件是否患病金融诈骗虚假账号 看到上面的例子&#xff0c;我们可以发现其中的特点&#xff0c;那就是都属于两个类别之间的判断。逻辑回归就是解决二分类问题的利器。 2、 逻辑回归的原理 2.1 输入 逻辑回归的输入就是一个线性…

Unity AI Muse 基础教程

Unity AI Muse 基础教程 Unity AI 内测资格申请Unity 项目Package ManagerMuse Sprite 安装Muse Texture 安装 Muse Sprite 基础教程什么是 Muse Sprite打开 Muse Sprite 窗口Muse Sprite 窗口 参数Muse Sprite Generations 窗口 参数Muse Sprite Generations 窗口 画笔Muse Sp…

基于RuoYi-Flowable-Plus的若依ruoyi-nbcio支持自定义业务表单流程(三)

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 相应的后端也要做一些调整 1、启动流程修改如下&#xff1a; /*** 启动流程实例*/private R startProce…

【应用程序代理对象ApplicationDelegate-应用程序启动过程介绍 Objective-C语言】

一、那我们接着昨天的内容,继续往下讲 1.有人对昨天最后这块儿内容有点儿晕,再捋一下吧, 1)我们刚开始的时候,是不是在Main.storyboard里面,放了一个按钮 2)我呢,想在点击按钮的时候,执行一些操作,对吧, 所以呢,我给它拖了一个事件, 拖到类实现里面, 3)那,首…

优秀的推荐系统架构与应用:从YouTube到Pinterest、Flink和阿里巴巴

文章目录 &#x1f31f; 业界经典&#xff1a;YouTube深度学习推荐系统的经典架构长什么样&#xff1f;&#x1f34a; 基础架构&#x1f34a; 深度学习模型&#x1f34a; 额外组件 &#x1f31f; 图神经网络&#xff1a;Pinterest如何应用图神经网络的&#xff1f;&#x1f34a…