【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.hqwc.cn/news/501547.html

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

相关文章

从链表中插入5个数,并排序

//从链表中插入5个数&#xff0c;并按小到大排序后输出 代码&#xff1a; #include <cstdio> #include <algorithm> using namespace std; struct Node {int Element;struct Node* Next;//指向下一个结点 }; bool comp(Node lhs, Node rhs) {return lhs.Element …

CentOS7使用yum安装MySQL8.0教程

CentOS7使用yum安装MySQL8.0 一、下载MySQL Yum下载仓库二、安装MySQL三、为MySQL运行提供相关的用户以及环境四、启动MySQL五、MySQL开机自启六、修改root账户密码 一、下载MySQL Yum下载仓库 MySQL下载地址&#xff1a;https://dev.mysql.com/downloads/ 首先进入下载页面&a…

MySQL的索引和B+tree结构

目录 0.关于索引的常见面试题 1.什么是索引&#xff1f; 索引的优缺点 2.索引的数据结构&#xff0c;为什么InnoDb引擎使用Btree作为索引的数据结构&#xff1f; 分析怎样的索引才是好的 二插搜索树 红黑树 B-Tree BTree 哈希 为什么 InnoDB 存储引擎选择使用 Btree 索…

附加Numpy数组

参考&#xff1a;Append Numpy Array 引言 在数据科学和机器学习领域&#xff0c;处理大规模数据集是一项重要且常见的任务。为了高效地处理数据&#xff0c;numpy是一个非常强大的Python库。本文将详细介绍numpy中的一个重要操作&#xff0c;即如何附加&#xff08;append&a…

Java多线程导入Excel示例

在导入Excel的时候&#xff0c;如果文件比较大&#xff0c;行数很多&#xff0c;一行行读往往速度比较慢&#xff0c;为了加快导入速度&#xff0c;我们可以采用多线程的方式 话不多说直接上代码 首先是Controller import com.sakura.base.service.ExcelService; import com.s…

YOLOv8涨点技巧,添加SE注意力机制提升目标检测效果

目录 论文地址 摘要 SE结构图 代码实现 Squeeze Excitation SE-Inception and SE-ResNet yaml文件编写 完整代码分享 总结 论文地址 http://openaccess.thecvf.com/content_cvpr_2018/papers/Hu_Squeeze-and-Excitation_Networks_CVPR_2018_paper.pdf 摘要 卷积神…

Spring Cloud 构建面向企业的大型分布式微服务快速开发框架+技术栈介绍

分布式架构图 Cloud架构清单 Commonservice&#xff08;通用服务&#xff09; 1&#xff09;清单列表 2&#xff09;代码结构 Component&#xff08;通用组件&#xff09; 1&#xff09;清单列表 2&#xff09;代码结构 快速开发管理平台——云架构【系统管理平台】 一…

SpringBoot IOC之@Autowried原理

文章目录 目录 文章目录 前言 一、AutowiredAnnotationBeanPostProcessor 二、MergedBeanDefinitionPostProcessor执行 2.1 postProcessMergedBeanDefinition方法执行 2.2 postProcessProperties方法执行 ​编辑 总结 前言 SpringBoot的两大特性&#xff0c;控制反转&#xff0…

StarRocks——中信建投基于StarRocks构建统一查询服务平台

目录 一、需求背景 1.1 数据加工链路复杂 1.2 大数据量下性能不足&#xff0c;查询响应慢 1.3 大量实时数据分散在各个业务系统&#xff0c;无法进行联合分析 1.4 缺少与预计算能力加速一些固定查询 二、构建统一查询服务平台 三、落地后的效果与价值 四、项目经验总结…

构建产业图谱,实现产业链精准招商!

​产业链招商是一种以产业链为基础的招商引资方式&#xff0c;它不仅仅关注单个企业的引入&#xff0c;而是侧重于整个产业链的布局和发展&#xff0c;通过吸引产业链上下游相关企业共同入驻&#xff0c;形成产业集群&#xff0c;从而提升地区或园区的产业竞争力和经济效益&…

C语言-----动态内存管理(1)

1.引入 我们之前已经学习了几种开辟内存空间的方式&#xff1a; &#xff08;1&#xff09;int a10;开辟4个字节大小的空间 &#xff08;2&#xff09;int arr[10]{0}定义数组开辟了一串连续的空间 2.malloc和free (1)malloc开辟内存空间可能会失败&#xff0c;因此需要检查…