【C++】STL简介 | STL六大组件 | string类 | string类对象操作

目录

1. 什么是STL

2. STL的版本 

3. STL的六大组件

4. STL的缺陷

5. 引出string类

6. 标准库中的string类

6.1 string类简介

6.2 string类对象的构造

6.3. string类对象的容量

6.4. string类对象的遍历

6.5. string类对象的修改

6.6. string类非成员函数

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


1. 什么是STL

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

2. STL的版本 

◆ 原始版本
Alexander Stepanov、Meng Lee 在惠普实验室完成的原始版本,本着开源精神,他们声明允许任何人任意运用、拷贝、修改、传播、商业使用这些代码,无需付费。唯一的条件就是也需要向原始版本一样做开源使用。 HP 版本--所有STL实现版本的始祖。

◆ P. J. 版本
由P. J. Plauger开发,继承自HP版本,被Windows Visual C++采用,不能公开或修改,缺陷:可读性比较低,符号命名比较怪异。

◆ RW版本
由Rouge Wage公司开发,继承自HP版本,被C++ Builder采用,不能公开或修改,可读性一般。

◆ SGI版本
由Silicon Graphics Computer Systems,Inc公司开发,继承自HP版本。被GCC(Linux)采用,可移植性好,可公开、修改甚至贩卖,从命名风格和编程风格上看,阅读性非常高。我们后面学习STL要阅读部分源代码,主要参考的就是这个版本。

3. STL的六大组件

4. STL的缺陷

  1. STL库的更新太慢了。这个得严重吐槽,上一版靠谱是C++98,中间的C++03基本一些修订。C++11出来已经相隔了13年,STL才进一步更新。
  2. STL现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。
  3. STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。
  4. STL的使用会有代码膨胀的问题,比如使用vector/vector/vector这样会生成多份代码,当然这是模板语法本身导致的。

5. 引出string类

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

6. 标准库中的string类

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

6.2 string类对象的构造

(constructor)函数名称

功能说明

string()   

构造空的string类对象,即空字符串

string(const char* s)   

用字符串来构造string类对象

string(const string &s)   

拷贝构造函数

string (const string& s, size_t pos, size_t len = npos);

从第pos个位置拷贝npos个

string(size_t n, char c)

string类对象中包含n个字符c

void Teststring()
{string s1;                //构造空的string类对象s1string s2("hello word");  //用字符串构造string类对象s2string s3(s2);            //拷贝构造s3string s4(s2,5,3);        //拷贝构造s2,从第5个位置开始(从0开始)取3个字符string s5(s2,5,10);	      //拷贝构造s2,从第5个位置开始,取10个字符,不够,有多少取多少string s6(s2,5);          //拷贝构造s2,从第5个位置开始,取余下的cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;cout << s5 << endl;cout << s6 << endl;
}int main()
{Teststring();return 0;
}

6.3. string类对象的容量

函数名称

功能说明

size  (重点)

返回字符串有效字符长度

length

返回字符串有效字符长度

capacity

返回空间总大小

empty   (重点)

检测字符串释放为空串,是返回true,否则返回false

clear   (重点)

清空有效字符

reserve   (重点)

为字符串预留空间

resize   (重点)

将有效字符的个数该成n个,多出的空间用字符c填充

void Teststring2()
{string s1("hello word");for(size_t i=0;i<s1.size();i++){cout << s1[i] << " ";			  //这里的[]实际是调用的运算符重载cout << s1.operator[](i) << " ";  //[]运算符重载}cout << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;
}int main()
{Teststring2();return 0;
}

查看扩容机制: 

void Teststring2()
{string s1("hello word");for(size_t i=0;i<s1.size();i++){cout << s1[i] << " ";			  //这里的[]实际是调用的运算符重载cout << s1.operator[](i) << " ";  //[]运算符重载}cout << endl;cout << s1.size() << endl;cout << s1.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 res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,  reserver不会改变容量大小。
6.4. string类对象的遍历

函数名称

功能说明

operator[ ]   

返回pos位置的字符,  const string类对象调用

begin+ end

begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器

rbegin + rend

begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭 代器

范围for

C++11支持更简洁的范围for的新遍历方式

用迭代器遍历

void Teststring3()
{string s1("hello word");const string s2("hello word");string::iterator it1 = s1.begin();   //begin为开始位置while(it1 != s1.end())				 //end为最后的下一个位置{cout << *it1 << " ";++it1;}string::const_iterator it2 = s2.begin();   //const迭代器,只读,不可以修改while(it1 != s2.end())				{cout << *it2 << " ";++it2;}}void Teststring4()
{string s1("hello word");string::reverse_iterator rit = s1.rbegin();  //反向迭代器while(rit != s1.rend())				 {cout << *rit << " ";++rit;}
}
6.5. string类对象的修改

函数名称

功能说明

push_back

在字符串后尾插字符

append

在字符串后追加一个字符串

operator+= (重点)

在字符串后追加字符串

c_str(重点)

返回C格式字符串

find + npos(重点)

从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置

rfind

从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置

substr

在str中从pos位置开始,截取n个字符,然后将其返回

void Teststring4()
{string s1("hello word");s1.push_back('!');cout << s1 << endl;s1.append("hello bit");cout << s1 << endl;s1.append(10,'x');cout << s1 << endl;}

注意:

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

函数

功能说明

operator+

尽量少用,因为传值返回,导致深拷贝效率低

operator>>   (重点)

输入运算符重载

operator   (重点)

输出运算符重载

getline   (重点)

获取一行字符串

relational operators   (重点)

大小比较

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

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

vs下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;

◆ 这种设计也是有一定道理的大多数情况下字符串的长度都小于16string对象创建好之后部已经有了16个字符数组的固定空间需要通过堆创建效率高

◆ 其次:还有一个size_t字段保存字符串长度一个size_t字段保存从堆上开辟空间总的容量

◆ 最后:还有一个指针做一些其他事情

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

g++string的结构

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

◆ 空间总大小

◆ 字符串有效长度

◆ 引用计数

◆ 指向堆空间的指针用来存储字符串

struct _Rep_base
{size_type    _M_length;size_type    _M_capacity;_Atomic_word _M_refcount;
};   

本章完。

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

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

相关文章

使用滤镜属性将网页从彩色变黑白

在某些情况下&#xff0c;例如为了表达哀悼或纪念&#xff0c; 许多网站会将页面颜色从彩色调整为黑白灰色。我到网上查找答案&#xff0c;发现有些是通过javascript或jQuery实现的&#xff0c;我试了一下居然无效。 后来找到一个方法&#xff0c;是仅用一行CSS代码就能搞定的&…

基于CNN-LSTM-Attention的时间序列回归预测matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1卷积神经网络&#xff08;CNN&#xff09;在时间序列中的应用 4.2 长短时记忆网络&#xff08;LSTM&#xff09;处理序列依赖关系 4.3 注意力机制&#xff08;Attention&#xff09; 5…

MySQL 学习记录 2

原文&#xff1a;https://blog.iyatt.com/?p13818 13 存储引擎 查看一下前面创建的一张表的创建语句&#xff0c;当时并没有显式指定引擎&#xff0c;MySQL 自动指定的 InnoDB&#xff0c;即默认引擎是这个。 创建表的时候要显式指定引擎可以参考这个语句 查看当前 MySQL …

【牛客】SQL130 试卷发布当天作答人数和平均分

描述 现有用户信息表user_info&#xff08;uid用户ID&#xff0c;nick_name昵称, achievement成就值, level等级, job职业方向, register_time注册时间&#xff09;&#xff0c;示例数据如下&#xff1a; iduidnick_nameachievementleveljobregister_time11001牛客1号31007算…

rke方式安装k8s集群

一、新机环境准备 1.1主机名设置 hostnamectl set-hostname XXX1.2 主机名与ip地址解析 vim /etc/hosts 192.168.0.140 rke 192.168.0.147 master1 192.168.0.152 node1 192.168.0.153 node21.3安装docker tar -xf docker-20.10.24.tgz cp ${SHELL_FOLDER}/docker/*…

【java】19:内部类(3)

成员内部类&#xff1a; 1.可以直接访问外部类的所有成员&#xff0c;包含私有的 class Outer01{//外部类 private int n1 10; public String name "张三"; class Innter01{ public void say0(){ System.out.println("Outer01 的n1 " n1 " outer…

JWT基于Cookie的会话保持,并解决CSRF问题的方案

使用JWT进行浏览器接口请求&#xff0c;在使用Cookie进行会话保持传递Token时&#xff0c;可能会存在 CSRF 漏洞问题&#xff0c;同时也要避免在产生XSS漏洞时泄漏Token问题&#xff0c;如下图在尽可能避免CSRF和保护Token方面设计了方案。 要点解释如下&#xff1a; 将JWT存入…

Snagit 2024:让你的屏幕活动瞬间变得生动有力 mac/win版

Snagit 2024 屏幕录制与截图软件是一款功能强大的工具&#xff0c;专为现代用户设计&#xff0c;以满足他们在工作、学习和娱乐中对屏幕内容捕捉和分享的需求。这款软件结合了屏幕录制和截图功能&#xff0c;为用户提供了一种高效、便捷的方式来捕捉屏幕上的精彩瞬间。 Snagit…

xxl-job--01--简介

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.xxl-job1. 1 发展历史1.2 XXL-JOB的系统架构1.3 xxl-job与其他框架对比 2. XXL-JOB的使用2.1 准备工作- 配置调度中心XXL-JOB的数据表 2.2 配置执行器1 引入依赖包…

vue cesium加载点与定位到指定位置

vue cesium定位到指定位置 window.viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(point.longDeg, point.latDeg, 6500000), orientation: {heading: 6.2079384332084935, roll: 0.00031509431759868534, pitch: -1.535}, duration: 3})vue cesium加载点 …

【蛀牙】如何选择牙刷,牙膏和牙杯(含其他日常牙具:牙线,漱口水,冲牙器)

程序员生活指南之 【蛀牙】如何选择牙刷&#xff0c;牙膏和牙杯&#xff08;含其他日常牙具&#xff1a;牙线&#xff0c;漱口水&#xff0c;冲牙器&#xff09; 文章目录 一、如何选择牙刷&#xff0c;牙膏和牙杯1、如何选择牙刷2、如何选择牙膏3、如何选择牙杯 二、日常牙具&…

为什么HashMap的键值可以为null,而ConcurrentHashMap不行?

写在开头 今天在写《HashMap很美好&#xff0c;但线程不安全怎么办&#xff1f;ConcurrentHashMap告诉你答案&#xff01;》这篇文章的时候&#xff0c;漏了一个知识点&#xff0c;知道晚上吃饭的时候才凸显想到&#xff0c;关于ConcurrentHashMap在存储Key与Value的时候&…

【Java】面向对象之多态超级详解!!

文章目录 前言一、多态1.1 多态的概念1.2 多态的实现条件1.3 重写1.3.1方法重写的规则1.3.2重写和重载的区别 1.4 向上转型和向下转型1.4.1向上转型1.4.2向下转型 1.5 多态的优缺点1.5.1 使用多态的好处1.5.2 使用多态的缺陷 结语 前言 为了深入了解JAVA的面向对象的特性&…

基于yolov5的电瓶车和自行车检测系统,可进行图像目标检测,也可进行视屏和摄像检测(pytorch框架)【python源码+UI界面+功能源码详解】

功能演示&#xff1a; 基于yolov5的电瓶车和自行车检测系统_哔哩哔哩_bilibili &#xff08;一&#xff09;简介 基于yolov5的电瓶车和自行车检测系统是在pytorch框架下实现的&#xff0c;这是一个完整的项目&#xff0c;包括代码&#xff0c;数据集&#xff0c;训练好的模型…

协程库项目—日志模块

日志模块程序结构图 sylarLog ├── LogLevel&#xff08;日志级别封装类&#xff09; │ ├── 提供“从日志级别枚举值转换到字符串”、“从字符串转换相应的日志级别枚举值”等方法 ├── LogEvent&#xff08;日志事件类&#xff09; │ ├── 封装日志事件的属性…

Unity(第二十一部)动画的基础了解(感觉不了解其实也行)

1、动画组件老的是Animations 动画视频Play Automatically 是否自动播放Animate Physics 驱动方式&#xff0c;勾选后是物理驱动Culling Type 剔除方式 默认总是动画化就会一直执行下去&#xff0c;第二个是基于渲染播放&#xff08;离开镜头后不执行&#xff09;&#xff0c; …

高性能服务系列【二】CPU和内存

现代计算机的系统架构十分复杂。在服务器中&#xff0c;双路处理器已经十分常见。最近Arm处理器实现双路共384核心&#xff0c;要知道目前Linux内核最高只支持256核&#xff0c;这就有点尴尬。 多路处理器将越来越普遍&#xff0c;对性能的影响和传统架构有不小的差别&#xf…

MySQL中json类型的字段

有些很复杂的信息&#xff0c;我们一般会用扩展字段传一个json串&#xff0c;字段一般用text类型存在数据库。mysql5.7以后支持json类型的字段&#xff0c;还可以进行sql查询与修改json内的某个字段的能力。 1.json字段定义 ip_info json DEFAULT NULL COMMENT ip信息, 2.按…

GO基本类型一些记录

基本类型一些记录 1.直接粘贴文本进println(" ")2.中文字符串长度别用len( )3.byte本质是uint8 1.直接粘贴文本进println(" ") GoLand会自动补充转义符 2.中文字符串长度别用len( ) 用相应编码库的方法&#xff0c;一般utf8即可 utf8.RuneCountInStrin…

PySide6实现word转化pdf

目录 一:实现思路 二:实现代码 三:完整代码和界面 一:实现思路 利用PySide6创建两个按钮和一个显示区域,一个选择文件按钮,一个转化按钮和信息展示,操作文件按钮选择一个待转化的word文档。并且展示文件路径到信息展示区,操作转化按钮,读取选择的文件转化为pdf。并…