C++ 之 string类 详细讲解

news2025/1/15 20:36:08

喜欢的人有点难追怎么办

那就直接拉黑

七个女生在一起是七仙女,那七个男生在一起是什么?

葫芦七兄弟

目录

一、为什么要学习string类

二、标准库中的string类

1.string类

2.string类的常用接口说明

2.1 string类对象的常见构造

2.2 string类对象的容量操作

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

2.4 string类对象的修改操作

2.5 string类非成员函数

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

4.浅拷贝和深拷贝讲解

5.写时拷贝(了解)

三、完结撒❀


一、为什么要学习string类

C语言中的字符串

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

常见面试题

比如:字符串相加

在OJ中,有关字符串的题目基本以string类的形式出现,而且在常规工作中,为了简单、方便、快捷、基本都使用string类,很少人去使用C库字符串中的操作函数。

二、标准库中的string类

1.string类

string类的文档介绍

在使用string类时,必须包含#include<iostream>头文件以及using namespace std

大家可以看一下上面string类的文档,简单学习一下string类的各种接口的作用和用法等等,不要抗拒英文文档,阅读英文文档是程序员必修课之一,下面我们只讲解标准库中string类的常用接口说明。

2.string类的常用接口说明

2.1 string类对象的常见构造

constructor函数名称功能说明
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类对象s1
    string s2("hello bit"); // 用C格式字符串构造string类对象s2
    string s3(s2); // 拷贝构造s3
}

2.2 string类对象的容量操作

函数名称功能说明
size(重点)返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间大小
empty(重点)检测字符串是否释放为空串,是返回true,否则返回false
clear(重点)清空有效字符
reserve(重点)为字符串开辟空间
resize(重点)将有效字符的个数改成n个,多出的空间用字符c进行填充

对于上面每个string容量相关使用方法在相应文档中就有很详细明确的使用举例,大家可以在文档中学习如何使用。

比如size:

注意:

1.size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,因为在size()出现之前都用的是length(),现在一般情况下都是用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的底层总空间大小时,reserve不会改变容量空间大小。

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

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

使用可以看文档中的举例

2.4 string类对象的修改操作

函数名称功能说明
push_back在字符串后尾插字符c
append在字符串后追加一个字符串
operator+=(重点)在字符串后追加一个字符串
c_str(重点)返回C格式字符串
find + npos(重点)从字符串pos位置开始往后找字符c,返回该字符串在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

大家要有能力阅读英文文档学习,使用举例在所给文档里面就有😘

注意:


1.在string尾部追加字符时,s.push_back(c)/s.append(1,c)/s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

2.对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间开辟好。

2.5 string类非成员函数

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

上面的几个接口大家了解一下,在以后写相关OJ题目中会有一些体现他们的使用。

string类中还有一些其他的操作,这里不一一列举,大家在需要时不明白查文档即可。

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

~ VS下的string的结构

string在VS上面总共占28个字节,内部结构稍微复杂一点,先是有一个联合体,联合体用来定义string中字符串的存储空间:
   ●   当字符串长度小于16时,使用内部固定空间字符数组来存放(在VS中string类内部有开辟出来一个固定长度16的字符串)。

   ●   当字符串长度大于等于16时,从堆上开辟空间。

union _Bxty
{   // storage for small buffer or pointer to larger one
    value_type _Buf[_BUF_SIZE];
    pointer _Ptr;
    char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;

这种设计肯定有它的好处,大多数情况下字符串长度都小于16,那string对象创建好之后,内部已经有了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;
};

●   指向堆空间的指针,用来存储字符串。

4.浅拷贝和深拷贝讲解

~ 浅拷贝

浅拷贝:也称位拷贝,编译器只是将对象中的值拷贝过来。如果对象中管理资源,最后就会导致多个对象共享同一份资源,当一个对象销毁时就会将该资源释放掉,而此时另一些对象不知道该资源已经被释放,以为还有效,所以当继续对资源进项操作时,就会发生发生了访问违规

就像一个家庭中有两个孩子,但父母只买了一份玩具,两个孩子愿意一块玩,则万事大吉,万一不想分享就你争我夺,玩具损坏。

可以采用深拷贝解决浅拷贝问题,即:每个对象都有一份独立的资源,不要和其他对象共享。父母给每个孩子都买一份玩具,各自玩各自的就不会有问题了。

~深拷贝

如果一个类中涉及到资源的管理,其拷贝构造函数、赋值运算符重载以及析构函数必须要显式给出。一般情况都是按照深拷贝方式提供。

深拷贝代码举例:
 

	string (const string& s)
	{
		_str = new char[s._capacity+1];//完成深拷贝
		strcpy(_str, s._str);
		_size = s._size;
		_capacity = s._capacity;
	}

简单来说,浅拷贝就是两个对象存储共用了同一块空间,而深拷贝就是两个对象存储用了两个不同的空间。

5.写时拷贝(了解)

写时拷贝就是一种拖延症,是在浅拷贝的基础之上增加了引用计数的方式来实现的。


引用计数:用来记录资源使用者的个数。在构造时,将资源的计数给成1,每增加一个对象使用该资源,就给计数增加1,当某个对象被销毁时,先给该计数减1,然后再检查是否需要释放资源,如果计数为1,说明该对象是资源的最后一个使用者,将该资源释放;否则就不能释放,因为还有其他对象在使用该资源。

当要修改该对象时,如果计数为1,说明该对象时资源的最后一个使用者直接修改即可,如果计数大于1,那么就需要拷贝出一块新空间再进行修改,这就叫写时拷贝。

三、完结撒❀

如果以上内容对你有帮助不妨点赞支持一下,以后还会分享更多编程知识,我们一起进步。
最后我想讲的是,据说点赞的都能找到漂亮女朋友❤

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

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

相关文章

KEITHLEY(吉时利)2440源测量单位(SMU)数字源表

KEITHLEY(吉时利&#xff09;2440源测量单位&#xff08;SMU)数字源表 主要特性 50W 时性能高达 5A / 40V0.012&#xff05; 基本测量精度&#xff0c;具有 6 位分辨率10pA / 100nV 测量分辨率与 KickStart 软件结合使用美国2440吉时利keithley数字源表特点 2400系列提供宽动…

HarmonyOS开发:【基于命令行(开发环境)】

准备开发环境 在嵌入式开发中&#xff0c;很多开发者习惯于使用Windows进行代码的编辑&#xff0c;比如使用Windows的Visual Studio Code进行OpenHarmony代码的开发。但当前阶段&#xff0c;大部分的开发板源码还不支持在Windows环境下进行编译&#xff0c;如Hi3861、Hi3516系…

三维图形学基础-三维点集求凸包算法

在计算凸包时&#xff0c;我们想要找到一个最小的凸多面体&#xff0c;它包含了给定点集合中的所有点&#xff0c;并且多面体的边界是由这些点确定的。凸包在计算机图形学、地理信息系统、机器人运动规划等领域中都有广泛的应用。 之前文字有讲到CGAL这个几何算法库&#xff0…

【UE C++】设置游戏模式

问题 我们都知道如何使用蓝图创建一个游戏模式并且在这个游戏模式蓝图中去设置“默认pawn类”、“HUD类”、“玩家控制器类”、“游戏状态类”、“玩家状态类”、“旁观者类”。那么如何使用C完成该操作呢&#xff1f; 步骤 1. 首先创建“GameMode”、“GameState”、“HUD”…

nginx 配置 SSL 证书实现 https 访问

nginx 配置SSL证书实现https访问 1. SSL 证书简介与获取1.1 SSL 证书介绍1.2 获取 SSL 证书 2. nginx 配置 SSL 文件2.1 SSL 文件放置与配置文件修改2.1.1 文件配置2.1.2 强制 https 访问 2.2 验证配置结果 同步发布在个人笔记 nginx 配置 SSL 证书实现 https 访问 配置好 ngi…

【嵌入式linux】Ubuntu 修改用户名

第一次打开Ubuntu时不小心把初始用户名“siriusiot”写成“siriousiot”&#xff08;多了一个o&#xff09; 。作为技术人&#xff0c;我们要保持严谨&#xff0c;我们要纠正过来&#xff08;其实就是单词拼错了怕被笑话&#xff09;。 打开终端&#xff0c;输入&#xff1a; …

WEB攻防-ASP安全-MDB下载

MDB下载漏洞主要涉及到早期ASPAccess构架的数据库文件。当Web站点提供文件下载功能时&#xff0c;如果没有对下载请求进行充分的验证和过滤&#xff0c;或者服务器配置不当&#xff0c;就可能产生文件下载漏洞。攻击者可以利用这个漏洞&#xff0c;通过修改请求参数或尝试猜测或…

Composer初次接触

php一直都是简单处理一下单片机的后台服务&#xff0c;没什么深入研究 今天安装一个 php composer.phar require qiniu/php-sdkComposer完全不懂&#xff0c;照着一试&#xff0c;就报错了 - topthink/think-installer v1.0.12 requires composer-plugin-api ^1.0 -> found…

什么是OCR转换?

OCR转换是指将图片或扫描文档中的文字内容转换成电子文本的过程。OCR代表光学字符识别&#xff08;Optical Character Recognition&#xff09;&#xff0c;是一种通过算法和模型来识别图像或文档中的文字&#xff0c;并将其转换成可编辑、可搜索的文本格式。OCR转换通常包括以…

分布式-知识体系

分布式系统 本质就是一堆机器的协同&#xff0c;要做的就是用各种手段来让机器的运行达到预期 分布式业务场景 分布式四纵四横说 基于 MSA&#xff08;微服务架构&#xff09;的分布式知识体系 相关概念 – 【摘自网络原文】 节点与网络 节点 传统的节点也就是一台单体的物…

AI预测体彩排列3第2套算法实战化测试第3弹2024年4月25日第3次测试

今天继续进行新算法的测试&#xff0c;今天是第3次测试。好了&#xff0c;废话不多说了&#xff0c;直接上图上结果。 2024年4月25日体彩排3预测结果 6码定位方案如下&#xff1a; 百位&#xff1a;4、5、3、6、1、0 十位&#xff1a;6、5、4、3、1、0 个位&#xff1a;6、2、7…

Lock-It for Mac(应用程序加密工具)

OSXBytes Lock-It for Mac是一款功能强大的应用程序加密工具&#xff0c;专为Mac用户设计。该软件具有多种功能&#xff0c;旨在保护用户的隐私和数据安全。 Lock-It for Mac v1.3.0激活版下载 首先&#xff0c;Lock-It for Mac能够完全隐藏应用程序&#xff0c;使其不易被他人…

【UE C++】重写基类中的BeginPlay、Tick函数

前言 为了让游戏场景中的各种继承于“Actor”的游戏对象在生命周期中执行自定义逻辑和行为&#xff0c;我们通常需要重写“Actor”类及其派生类中的BeginPlay、Tick函数。 那么如何用C重写BeginPlay、Tick函数呢&#xff0c;可参考如下步骤。 步骤 1. 在头文件中添加如下代码…

consul服务注册与发现、服务配置与刷新

为什么要用服务注册&#xff1f;为什么要用consul不用eureka&#xff1f; 举个栗子&#xff1a; 微服务当中存在多个服务模块&#xff0c;每个服务模块的ip端口在每套环境是不一致的&#xff0c;开发切换环境部署时&#xff0c;如果漏了一个配置忘记改动&#xff0c;将是一个很…

如何开启kali的ssh远程连接

1.打开配置文件 vim /etc/ssh/sshd_config 将第13行和32改为如下&#xff0c;保存退出 重启服务 sudo systemctl restart ssh.service 使用远程工具&#xff08;如xshell&#xff09;即可连接 如果无法连接&#xff0c;需要先生成两个密钥&#xff1a;ssh-keygen -t dsa -f…

Web APIs 学习归纳1---Web API概述简单的元素获取

JS基础中我们学习了JS的基本语句&#xff0c;这些是后续学习中的基础。 有了上述JS的基础以后&#xff0c;我们就可以开始学习交互效果的实现方法。这里很多时候直接调用JS封装好的API即可。 一、Web APIs 和 JS 基础关联性 这里有一张图很好的解释了这个问题&#xff1a; 我们…

离线模式下载安装gcc-4.8.5

目录 一&#xff0c;下载gcc离线安装包 二&#xff0c;下载gcc依赖包 三&#xff0c;安装gcc 1, 解压 2, 将依赖库放置环境 3, 安装 3.1自动安装 3.1.1 执行依赖库的编译 3.1.2 新建编译目录 3.1.3 配置编译环境 3.1.4 编译 3.1.5 安装 3.2 手动安装 3.2.…

扫码怎样上传现场照片或视频?快速提交现场记录的方法

现在很多应用场景会使用二维码来登记信息&#xff0c;通过手机扫描二维码即可根据问题填写对应的数据&#xff0c;比如在活动签到、预约报名、巡视检查、用户调研等场景现在都会采用这种方式来登记信息。有些时候需要扫码者在填写数据时上传现场相关照片或者视频来作为证明&…

Unity Meta Quest MR 开发(七):使用 Stencil Test 模板测试制作可以在虚拟与现实之间穿梭的 MR 传送门

文章目录 &#x1f4d5;教程说明&#x1f4d5;Stencil Test 模板测试&#x1f4d5;Stencil Shader&#x1f4d5;使用 Unity URP 渲染管线设置模板测试⭐Render Pipeline Asset 与 Universal Renderer Data⭐删除场景中的天空盒⭐设置虚拟世界的层级 Layer⭐设置模板测试 &#…

FreeRTOS:3.消息队列

FreeRTOS消息队列 本文主要基于消息队列的源码进行分析&#xff0c;来对FreeRTOS的消息队列进一步学习。 消息队列非常重要&#xff0c;因为后面的各种信号量基本都是基于队列的&#xff0c;搞清楚消息队列的源码&#xff0c;也就搞清楚消息队列的原理。 参考链接&#xff1…