【C++】从string开始了解STL

文章目录

  • 1.初识STL
    • 1.什么是STL
    • 2.STL的版本
    • 3.STL的六大组件
  • 2.string
    • 1.string类模板
    • 2.string类的构造函数
    • 3.string内部数据访问
    • 4.string的遍历
    • 5.string类的迭代器
    • 6.string的Capacity相关接口
    • 7.string的修改相关接口
    • 8.其他接口

1.初识STL

1.什么是STL

STL(standard template libaray-标准模板库):是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的六大组件

image-20230413011601095

对于STL的学习,这里推荐一个网站cplusplus.com

2.string

接下来就要正式进入到对STL的学习中啦,在对STL的学习过程中,需要注意的是

第一、熟悉库里面的STL的各种类模板的常用接口

第二、尝试去模拟实现库里面的类模板

注:在过程中,我们可能会遇到一些没有办法解决的问题,此时将会去查库里的源码,由于各个库中的实现方式不太一样,所以,在这里定一下,我们将会参考SGI版本的代码,结合侯捷老师的STL源码剖析去模拟实现。

1.string类模板

我们打开上文中推荐的网站,搜索string,会发现我们平常用的string其实是basic_string<char>,是类模板basic_string实例化出来的char类。

image-20230413164133833

basic_string是一个类模板,可以通过传入不同的类型参数实例化出不同的类。

image-20230413164426971

那么,对于string,为什么要使用一个类模板呢,在C语言中,对于字符串都是能够存放char类型的数据就可以了?

这是因为编码的问题,我们知道,在计算机中存放的数据都是0和1,为了让数据转换成人能看懂的东西,人们把特定的01序列给定义成某个字符,按照这种方式可以将计算机中的数据翻译出来,这就是编码,最初的编码方式就是将一些符号和大小写的26个字母与01序列对应,这就是ASCII码。

现在的常见编码方式

  • ASCII码

    美国信息交换标准代码,是计算机存值和文字符号的对应关系,只有256个字符

  • Unicode

    万国码,是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码包括了utf-8,utf-16,utf-32

    utf-8兼容了ASCII,utf-8使用比较普遍,也比较节省空间

  • gbk

    gbk即国标,针对中文而设计的编码,采用双字节编码

2.string类的构造函数

首先,一个类中必不可少的就是构造函数,我们来看一下string类的构造函数有什么

image-20230413210421519

以上就是string的所有构造函数了,接下来让我们通过代码来实验一下:

void Test_Construct()
{
	char str[] = "hello string";//创建一个C语言的字符串
	string s1;//默认构造函数,不用传递任何参数,最终是s1中只有一个\0
	string s2(str);//使用C语言的字符串构造一个string类型的对象
	string s3(s2);//使用s2拷贝构造一个string类型的对象
	string s4(s3, 2, 5);//使用s3中的第二个位置开始长度为5的子串构造对象
	string s5(str, 8);//使用C语言的字符串构造一个指定长度的string类型
	string s6(10, 'a');//使用指定字符构造一个长度为10,内容为a的对象
	auto first = s2.begin();
	auto last = s2.end();
	string s7(first, last);//使用迭代器区间构造一个[first,last)的对象
	cout << "s1: " << s1 << endl;
	cout << "s2: " << s2 << endl;
	cout << "s3: " << s3 << endl;
	cout << "s4: " << s4 << endl;
	cout << "s5: " << s5 << endl;
	cout << "s6: " << s6 << endl;
	cout << "s7: " << s7 << endl;
}

运行上述代码,结果是:

image-20230413212541978

在上面的函数原型中,好像发现了一个之前没见过的东西,npos,什么是npos呢?查一下文档

image-20230413212851969

可以看到npos是在类中定义的一个公共的静态成员常量,这个常量定义的值为-1,但是由于常量的类型是size_t,即unsigned int,所以表示的此类型可能的最大值。我们理解成字符串的结尾即可。

由于npos是string类中的成员常量,所以在使用npos的时候需要指定类域,即string::npos.

3.string内部数据访问

image-20230413233845379

可以看到,对于数据访问,string提供了4个接口,其中两个是C++11新增的,看名字也可以得出,是获得字符串首元素和最后一个元素的,不常用,所以在此不过多赘述。我们主要关注at和operator[]这两个接口。

image-20230413234409535

image-20230413234429978

这两个接口都是能够拿到指定位置的值,其中operator[]是对[]的运算符重载。可以看到两个接口都重载了普通版本和const版本,用来应对权限放大的问题。

void Test_Element()
{
	string s = "hello string";
	cout << s.at(4) << endl;
	cout << s[4] << endl;
}

image-20230414000051982

4.string的遍历

对于string的遍历,我们有以下几种方法:

  1. operator[]
  2. 范围for
  3. 迭代器
void Test_Element2()
{
	string s = "0123456789";
	//operator[]
	for (size_t i = 0; i < s.size(); ++i)
	{
		cout << s[i] << " ";
	}
	cout << endl;
	//范围for
	for (auto e : s)
	{
		cout << e << " ";
	}
	cout << endl;
	//迭代器
	string::iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;
}

image-20230414001152126

5.string类的迭代器

在遍历中,我们讲到了迭代器的方式遍历字符串,那么迭代器是什么?为什么要有迭代器的存在?

迭代器是通过一种普适的方式去访问所有支持遍历的容器,迭代器的行为上像指针,但是本质上不全是指针

在string类中,原生指针就已经能够支持迭代器的行为,所以string的迭代器就是元素类型的指针。

image-20230413213824032

可以看到string提供了很多中不同的迭代器,我们可以将它们分类

1. 正向迭代器

begin和end,begin返回的是字符串的开头位置,end返回的是最后一个有效数据的下一个位置,即迭代器是前闭后开的*[begin,end)*

image-20230414001904042

image-20230414001919818

可以看到,不管是begin还是end都重载了const版本用来应对权限变化的问题。

2. 反向迭代器

反向迭代器与正向迭代器的用法完全一致,只是调用反向迭代器的时候,遍历数据的顺序是反的。

void Test_Iterator()
{
	string s = "0123456789";
	cout << "正向迭代器" << endl;
	string::iterator it1 = s.begin();
	while (it1 != s.end())
	{
		cout << *it1 << " ";
		++it1;
	}
	cout << endl;
	cout << "反向迭代器" << endl;
	string::reverse_iterator it2 = s.rbegin();
	while (it2 != s.rend())
	{
		cout << *it2 << " ";
		++it2;
	}
	cout << endl;
}

image-20230414002535594

3. const迭代器与const反向迭代器

这四个迭代器接口都是C++11为了规范代码而增加的,但是其实在前面四个接口中已经重载了const版本,所以这四个基本用不上,就不过多介绍了,使用方法和前面的是完全一致的。

6.string的Capacity相关接口

image-20230414002824152

在这么多接口中,我们最常用的有:

  • size:返回字符串长度
  • resize:重新设定字符串长度
  • capacity:返回字符串容量
  • reserve:重新设置字符串容量,如果传入的参数小于capacity则不做任何操作,如果大于capacity就开辟一段容量为n的空间,将原数据拷贝进来,然后释放原空间。
  • empty:返回字符串是否为空

其余的一些接口不常用,了解即可。

void Test_capacity()
{
	string s = "0123456789";
	cout << "size" << s.size() << endl;
	cout << "capacity" << s.capacity() << endl;
	s.reserve(20);
	cout << "capacity" << s.capacity() << endl;
	s.resize(5);
	cout << "size" << s.size() << endl;
	if (!s.empty())
	{
		string::iterator it1 = s.begin();
		while (it1 != s.end())
		{
			cout << *it1 << " ";
			++it1;
		}
		cout << endl;
	}
	else
	{
		cout << "string is empty" << endl;
	}

}

image-20230414003555655

7.string的修改相关接口

image-20230414003646756

其中,常用的有

  • operator+=:追加字符串,其中有三个重载,分别是追加字符串(复用append),追加C类型字符串(复用append),追加单个字符(复用push_back)
  • insert:在某个位置插入字符或者字符串
  • erase:在某个位置删除字符或者长度为len的字符串
void Test_Modify()
{
	string s = "abcdefg";
	cout << s << endl;
	s += 'h';
	cout << s << endl;
	s += "ijklm";
	cout << s << endl;
	s.insert(5, 1, 'A');
	cout << s << endl;
	s.erase(5, 1);
	cout << s << endl;
}

image-20230414004529694

8.其他接口

  • c_str:以C语言字符串的方式返回一个字符指针(由于Linux是用C语言写的,在字符串的读写中,不支持string类型的读写,所以提供此接口)
  • find:在字符串某一段位置中找到某个值,如果找到了就返回下标,否则返回npos
  • getline:读取缓冲区的数据直到遇到换行符,这是为了防止出现cin遇到空格停止读取,无法将后续内容放入同一个字符串中
  • operator>>和operator<<:重载流插入和流提取,使字符串也支持cin和cout的用法

写在最后:

1. 由于这是第一次接触到STL,所以将很多的成员函数接口讲解的比较细致,后续的STL容器的接口将会省略掉一些重复的和相似性很高的函数。
2. 关于某个类的使用,是不可能用一篇博客说明白的,还是要在实践中学习,多看看文档里的内容

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

openpnp - 顶部相机 - 辅助光(环形灯)的电路原理图

文章目录 openpnp - 顶部相机 - 辅助光(环形灯)的电路原理图概述END openpnp - 顶部相机 - 辅助光(环形灯)的电路原理图 概述 同学帮我做的简易灯板设计不太合理, 发热量极大. 想看看商用的环形灯电路啥样的, 如果有可能, 自己做块灯板, 塞进商用环形灯外壳中. 拆解了一个环形…

从TOP25榜单,看半导体之变

据SIA报告显示&#xff0c;2022年全球半导体销售额创历史新高达到5740亿美元。尽管2022年下半年&#xff0c;半导体市场出现了周期性的低迷&#xff0c;但其全年的销售额相较2021年增长了3.3%。 近日&#xff0c;市调机构Gartner发布了全球以及中国大陆TOP25名半导体厂商的排名…

【软考数据库】第二章 程序语言基础知识

目录 2.1 程序设计语言的基本概念2.2 程序设计语言的基本成分2.3 编译程序基本原理 前言&#xff1a; 笔记来自《文老师软考数据库》教材精讲&#xff0c;精讲视频在b站&#xff0c;某宝都可以找到&#xff0c;个人感觉通俗易懂。 2.1 程序设计语言的基本概念 程序设计语言是…

《3-链表》

链表 引言&#xff1a; 存储数组需要内存空间连续&#xff0c;当我们需要申请一个很大的数组时&#xff0c;系统不一定存在这么大的连续内存空间。 而链表则更加灵活&#xff0c;不需要内存是连续的&#xff0c;只要剩余内存空间大小够用即可 1.定义 &#xff1a; 「链表 Lin…

文本批量翻译-批量翻译文件名

批量将英文翻译成中文的软件 批量将英文翻译成中文的软件的主要用途场景主要是在需要大量翻译英文文本到中文的场景下使用&#xff0c;例如&#xff1a; 商务文件翻译&#xff1a;许多企业需要将其商务文件&#xff0c;如合同、报告、信函等翻译成中文&#xff0c;以便其中文读…

Vulnhub项目:MrRobot

靶机地址&#xff1a;Mr-Robot: 1 ~ VulnHub 渗透过程&#xff1a; 先看描述&#xff0c;有3跟keys在这个靶机中 首先确定靶机ip&#xff0c;对靶机开放的端口进行探测 访问靶机地址&#xff0c;出现了很酷炫的web界面&#xff0c;这个mr.robot,是一个美剧&#xff0c;还是挺…

e-STUDIO2010AC•2520AC安装步骤

注意!在室内室外温差比较大的情况下,设备需要在室内静置240分钟以上才可以进行安装。

智慧园区综合管理平台开发基本功能有哪些?

随着智慧城市建设与信息化发展&#xff0c;园区管理也需要更加智能便捷化&#xff0c;于是智慧园区管理系统开发应运而生。智慧园区综合管理系统就是利用物联网、大数据等技术工具&#xff0c;顺应产业园区升级发展需求&#xff0c;实现园区环境、设备、安全、基础管理、资源服…

TensorFlow Lite,ML Kit 和 Flutter 移动深度学习:1~5

原文&#xff1a;Mobile Deep Learning with TensorFlow Lite, ML Kit and Flutter 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 深度学习 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 不要担心自己的…

vue关于echarts后端返回格式取值方法

在vue中&#xff0c;接口返回如下数据&#xff1a; data: {充电桩: [0, 0, 78], 红外摄像头: [0, 0, 0], 火焰探测器: [0, 1, 0], 烟雾传感器: [0, 1, 1], 限流保护器: [0, 0, 1]}&#xff0c; 其中数组里第一个值应该放在data1&#xff0c;第二个放在data2&#xff0c;第三个…

docker学习

安装 curl -fsSL https://get.docker.com -o get-docker.sh sudo sh get-docker.sh为了防止后面权限有问题&#xff0c;执行下面这个 sudo groupadd docker sudo gpasswd -a $USER docker newgrp docker基本操作 获得镜像 docker pull hello-world运行 docker run hello-w…

蓝桥杯欲伸手CTF?有多远爬多远

注意&#xff1a;网络安全类比赛 或者说 CTF 参赛不会需要任何费用 只有国赛/省赛有可能会收取一定运维费用 其他比赛都不会收费 望周知。 先来看个特离谱的事情 早上起床看到几位师傅的朋友圈一脸懵&#xff0c;再仔细一看&#xff0c;好嘛。。。。。。 先看看探姬的回复 接下…

如何使用ChatGPT在1天内完成毕业论文

如何使用ChatGPT在1天内完成毕业论文 几天前&#xff0c;亲眼见证了到一位同学花了1天时间用ChatGPT完成了他的毕业论文&#xff0c;世道要变&#xff0c;要学会使用黑科技才能混的下去。废话到此结束&#xff0c;下面说明这么用AI生成自己的论文。 使用工具&#xff1a; 1. P…

VMware vSphere 8.0 Update 1 正式版发布 - 企业级工作负载平台

ESXi 8.0 U1 & vCenter Server 8.0 U1 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-vsphere-8-u1/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 2023-04-18&#xff0c;VMware vSphere 8.0 Update 1 正式…

Excel技能之排名,小函数很强大

你还在熬夜加班搞Excel吗&#xff1f; 你还在用手指&#xff0c;指着电脑屏幕&#xff0c;一行一行核对数据吗&#xff1f; 你还在害怕被笑而不敢问同事吗&#xff1f; 赶紧来学Excel&#xff0c;收藏加关注&#xff0c;偷偷地进步&#xff01;日积月累&#xff0c;必成大器&am…

ADIDAS阿里纳斯励志广告语

系列文章目录 精选优美英文短文1——Dear Basketball&#xff08;亲爱的篮球&#xff09;精选优美英文短文2——Here’s to the Crazy Ones&#xff08;致疯狂的人&#xff09;“我祝你不幸并痛苦”——约翰罗伯茨毕业致辞“亲爱的波特兰——CJ麦科勒姆告别信” Hi, I’m Gilb…

Java阶段二Day05

Java阶段二Day05 文章目录 Java阶段二Day05截至此版本可实现的流程图为V14UserControllerClientHandlerDispatcherServletHttpServletResponseHttpServletRequest V15DispatcherServletHttpServletResponseHttpServletRequest V16HttpServletRequestHttpServletResponse 反射JA…

【Linux网络服务】DNS域名解析服务服务

一、BIND域名服务基础 服务背景 1在日常生活中人们习惯使用域名访问服务器&#xff0c;但机器向互相只认IP地址&#xff0c;域名与IP地址之间是多对一的关系&#xff0c;一个IP址不一定只对应一个域名&#xff0c;且一个完成域名只可以对应一个IP地址&#xff0c;它们之间转换…

【数据结构】解析队列各接口功能实现

目录 前言&#xff1a; 一、队列概述&#xff1a; 1.队列的概念&#xff1a; 二、队列的各种接口功能实现&#xff1a; 1.初始化队列&#xff1a; 2.入队&#xff08;尾插&#xff09;&#xff1a; 3.出队&#xff08;头删&#xff09;&#xff1a; 4.查看队头&#xf…

PyTorch 深度学习实战 | 基于 ResNet 的花卉图片分类

“工欲善其事&#xff0c;必先利其器”。如果直接使用 Python 完成模型的构建、导出等工作&#xff0c;势必会耗费相当多的时间&#xff0c;而且大部分工作都是深度学习中共同拥有的部分&#xff0c;即重复工作。所以本案例为了快速实现效果&#xff0c;就直接使用将这些共有部…