C++深入学习string类成员函数(2):容器管理
引言
C++ 标准库中的容器(如 std::string、std::vector、std::list 等)都提供了一系列容器管理成员函数,用于处理容器的大小、容量、清空等操作。容器管理成员函数可以分为几类,主要包括容量查询、修改容器大小、清空容器等操作。
以下是常见的容器管理成员函数(适用于大多数标准库容器,如 std::string, std::vector 等),我们在此只介绍这些成员函数在string类中的操作:
1.容量查询函数
这些函数用于查询容器的大小和容量信息。
1.1 size()与length()
size()和 length()作用相同,都用于返回字符串的长度,返回类型都是size_t。
(1)函数原型
size_t size() const noexcept;
size_t length() const noexcept;
- const:关键字const表示该函数是常量成员函数,即它不会修改当前对象的状态。
- noexcept:noexcept表示该函数在执行时不会抛出任何异常,即无论什么情况下,调用size()都不会引发异常。
(2)示例代码
#include <iostream>
using namespace std;int main()
{string s = "Hello";cout << s.size() << endl;//5cout << s.length() << endl;//5return 0;
}
两者没有功能上的区别,提供两个概念主要是为了与开发者的习惯保持一致,size_t()更符合容器类的术语,length()更符合处理字符串的自然语言概念。
1.2 capacity()
std::string 类中的 capacity() 函数用于返回当前字符串对象分配的内存容量大小(不包括末尾的空终止符 '\0'),这个容量表示在不重新分配内存的情况下,字符串最多可以容纳的字符数量。
- 与 size() 不同,size() 返回的是当前字符串中实际存储的字符数,而 capacity() 则表示分配的空间总量(不包括末尾的空终止符 `'\0'`),通常比 size() 大,特别是在进行字符串扩展时。
(1)函数原型
size_t capacity() const noexcept;
(2)示例代码
#include <iostream>
using namespace std;int main()
{string s1 = "Hello, Welcome";cout << s1.size() << endl;//7cout << s1.capacity() << endl;//15s1 += " to henu";cout << s1.size() << endl;//22cout << s1.capacity() << endl;//31return 0;
}
- 当字符串需要扩展并超出当前的容量时,系统会自动重新分配更多的内存空间,以容纳更多字符。
(2)总结
- capacity() 返回当前字符串分配的总内存量,可以在不重新分配内存的情况下容纳的最大字符数。
- capacity() 通常大于 size(),以避免频繁的内存分配操作,提高性能。
- 通过 reserve() 预分配内存,或者通过 shrink_to_fit() 释放未使用的空间,可以调整字符串的容量管理行为。
1.3 其它成员函数
1.3.1 max_size()
max_size():返回容器可以存储的最大元素数量,这并不是你实际分配到的内存容量,而是字符串理论上能达到的最大大小,由系统和标准库的实现决定。
size_t max_size() const noexcept;
#include <iostream>
using namespace std;int main()
{string s1 = "Hello";cout << s1.max_size() << endl;//9223372036854775807return 0;
}
1.3.2 empty()
empty():检查容器是否为空,返回布尔值 true 表示容器为空,false 表示不为空。
bool empty() const noexcept;
#include <iostream>
using namespace std;int main()
{string s1 = "Hello";string s2;cout << s1.empty() << endl;// 输出 0(false),因为 str 是不是空的cout << s2.empty() << endl;// 输出 1(true),因为 str 是空的return 0;
}
2. 修改容器大小的函数
这些函数用于修改容器的大小或容量。
2.1 reverse()
std::strin 类的 reserve() 函数用于预分配内存,调整字符串的 capacity,以避免在字符串扩展时频繁重新分配内存。这是一种优化技术,可以提高性能,尤其是在已知字符串将增长到较大大小的情况下
(1)函数原型
void reserve (size_t new_cap);
- new_cap:这是你希望字符串预分配的最小容量。如果 new_cap 小于当前 capacity(),调用 reserve() 不会减少现有的容量。如果 new_cap 大于当前 capacity(),则分配足够的内存以满足 new_cap 的要求。
- 默认行为:如果没有传递参数,默认行为是将字符串的容量保持为当前值,不会额外分配空间。
(2)关键点
- reserve() 只调整 capacity(),不影响当前字符串的 size() 和内容。
- 如果你提前知道字符串可能会变得很大,使用 reserve() 可以避免在多次添加字符时频繁地重新分配内存。
(3)示例代码
#include <iostream>
using namespace std;int main()
{string s1 = "Hello";cout << s1.size() << endl;//5cout << s1.capacity() << endl;//15s1.reserve(50);s1 += ", this is a long sentence that we are appending!";cout << s1.size() << endl;//53cout << s1.capacity() << endl;//63return 0;
}
调用 reserve(50) 后得到 63 个字符的容量是标准库的一种优化策略。C++ 标准库为了减少频繁的内存分配开销,通常会分配比你实际请求更多的内存,使用指数增长或倍数增长的方式来优化性能。因此,分配的容量可能大于你请求的大小,这是正常且预期的行为。
(4)总结
- reserve() 提前分配内存但不改变字符串的大小。
- 它优化了频繁增长的场景,减少了不必要的内存重新分配。
- 使用 reserve() 可以提高代码在处理大字符串时的性能。
2.2 其它成员函数
2.2.1 resize()
resize(size_type n)用来调整容器大小。若 n 大于当前大小,则增加新元素(对于 std::string,新增的字符是 \0 或指定的字符);若 n 小于当前大小,则移除多余的元素。
void resize (size_t n);
void resize (size_t n, char c);
它有两个重载版本:
1. resize(size_t n):将字符串的大小调整为 n,如果 n 小于当前大小,则截断字符串;如果 n 大于当前大小,则在字符串末尾添加空字符 `\0`。
2. resize(size_t n, char c):将字符串的大小调整为 n,如果 n 小于当前大小,则截断字符串;如果 n 大于当前大小,则在字符串末尾添加字符 c 来填充。
#include <iostream>
using namespace std;int main()
{string s1 = "Hello, henu";s1.resize(5);//调整字符串大小为5,截断字符串cout << s1 << endl;s1.resize(20, 'x');//调整字符串大小为20,用'x'填充字符串cout << s1 << endl;return 0;
}
- resize() 可以用来增大或缩小字符串的大小。
- 增大时可以用指定字符填充,不指定时使用空字符 `\0`。
- 缩小时会截断字符串。
2.2.2 shrink_to_fit()
shrink_to_fit() 用来缩小字符串的容量,使其与当前字符串的大小一致,释放多余的内存。
- 不过shrink_to_fit() 是非强制性的,标准库实现可以选择是否实际执行这个操作。通常取决于库的具体实现。尽管你调用了它,容量不一定会完全匹配大小,但库会尽量缩小容量。
void shrink_to_fit();
#include <iostream>
using namespace std;int main()
{string s1 = "Hello";cout << s1.size() << endl;//5cout << s1.capacity() << endl;//15s1.shrink_to_fit();cout << s1.size() << endl;//5cout << s1.capacity() << endl;//5return 0;
}
3. 清空和删除元素的函数
这些函数用于清空容器或删除元素。
3.1 clear()
clear()用来清空容器中的所有元素,使其 size 变为 0,它不会改变字符串的容量。
(1) 函数原型:
void clear() noexcept;
- 清空字符串内容,将字符串长度变为 0。
- 该函数是 noexcept 的,这意味着它保证不会抛出异常。
(2)示例代码:
#include <iostream>
using namespace std;int main()
{string s1 = "Hello, henu";cout << s1 << endl;//Hello, henucout << s1.size() << endl;//11cout << s1.capacity() << endl;//15s1.clear();//清空字符串cout << s1 << endl;//cout << s1.size() << endl;//0cout << s1.capacity() << endl;//15return 0;
}
(3) 总结:
- clear() 清空字符串的内容,长度变为 0。
- clear() 不会影响字符串的容量(即预分配的内存),如果你想释放多余的内存,可以结合使用 shrink_to_fit()。
- clear() 是一个非常高效的操作,适用于需要多次复用同一字符串的场景。
3.2 Erase
用于删除字符串中的一个或多个字符。它有几种不同的重载方式,允许根据不同的需求删除字符。
(1)函数原型:
sequence (1) string& erase (size_t pos = 0, size_t len = npos);
character (2) iterator erase (const_iterator p);
range (3) iterator erase (const_iterator first, const_iterator last);
1. erase(size_t pos = 0, size_t len = npos)
- 从字符串中删除从位置 pos 开始的 len 个字符。
- npos 是一个特殊值,表示“直到字符串的末尾”。
- 返回值是 this,即调用此函数的字符串自身。
2. iterator erase(const_iterator position)
- 删除迭代器 position 指向的字符。
- 返回值是一个指向删除元素之后元素的迭代器。
3. iterator erase(const_iterator first, const_iterator last)
- 删除从 first 到 last 范围内的字符(last 不包括在内)。
- 返回值是一个指向删除范围之后第一个字符的迭代器。
(2)示例代码
#include <iostream>
using namespace std;int main()
{string s1 = "Hello, henu";s1.erase(5, 2);//删除第五个字符后的两个字符cout << s1 << endl;//Hellohenus1.erase(5, 4);cout << s1 << endl;//Hellos1.erase(s1.begin());//删除Hcout << s1 << endl;//ellos1.erase(s1.begin() + 3);//删除ocout << s1 << endl;//ellstring s2 = "Hello, henu";s2.erase(s2.begin() + 5, s2.begin() + 10);//删除[',','u')之间的字符cout << s2 << endl;//Hellos1.erase();//删除整个字符串s2.erase();cout << s1 << endl;cout << s2 << endl;return 0;
}
(3)总结:
- erase() 可以删除从指定位置开始的一个或多个字符。
- 可以通过迭代器删除指定的字符或字符范围。
- erase() 是一个高效的操作,适用于修改字符串内容。
4. 交换函数
swap()能够交换两个容器的内容,它通过交换字符串的内部数据指针来实现,不涉及字符的逐一拷贝,因此操作非常高效,在效率上比逐个交换元素更好,时间复杂度为 O(1)。
(1)函数原型:
void swap (string& str);
- 交换当前字符串和参数 str 的内容。
- 由于是 noexcept 的函数,它保证不会抛出异常。
(2)示例代码:
#include <iostream>
using namespace std;int main()
{string s1 = "Hello";string s2 = "henu";s1.swap(s2);cout << s1 << endl;//henucout << s2 << endl;//Helloreturn 0;
}
swap() 函数的效率很高,因为它只交换字符串对象的内部指针,而不涉及字符的复制操作。
(3)全局 swap() 函数:
除了 std::string 的成员函数 swap() 之外,C++ 还提供了一个全局的 std::swap() 函数,可以用来交换任意两个类型相同的对象,包括 std::string:
#include <iostream>
using namespace std;int main()
{string s1 = "Hello";string s2 = "henu";//s1.swap(s2);swap(s1, s2);cout << s1 << endl;//henucout << s2 << endl;//Helloreturn 0;
}
(4)std::swap 和 string::swap 的区别:
- std::swap 是一个全局函数,可以交换任意类型的两个对象,不局限于 std::string。
- string::swap 是 std::string 类的成员函数,专门用于交换两个字符串对象。
总结:
容器管理成员函数主要用于处理容器的大小和容量,以下是它们的分类:
1. 容量查询函数:size()、length(),max_size(),capacity(),empty()。
2. 修改容器大小的函数:resize(),reserve(),shrink_to_fit()。
3. 清空和删除元素的函数:clear(),erase()。
4. 交换函数:swap()。
这些函数在容器的动态管理中非常常用,能够有效地控制容器的内存和元素管理。
更多string类的成员函数:string - C++ Reference (cplusplus.com)
相关文章:

C++深入学习string类成员函数(2):容器管理
引言 C 标准库中的容器(如 std::string、std::vector、std::list 等)都提供了一系列容器管理成员函数,用于处理容器的大小、容量、清空等操作。容器管理成员函数可以分为几类,主要包括容量查询、修改容器大小、清空容器等操作。 …...

MariaDB 和 MySQL 全面对比:选择数据库需要考虑这几点
谁在使用 MySQL 和 MariaDB? MySQL 和 MariaDB 都发布了各自的用户名单。 使用 MySQL 的有 Facebook、Github、YouTube、Twitter、PayPal、诺基亚、Spotify、Netflix 等。 使用 MariaDB 的有 Redhat、DBS、Suse、Ubuntu、1&1、Ingenico 等。 功能比较…...

Python 实现图形学几何变换算法
目录 Python 实现图形学几何变换算法几何变换介绍变换矩阵Python 实现几何变换代码解释总结 Python 实现图形学几何变换算法 在计算机图形学中,几何变换是非常重要的概念。它们允许我们对对象的位置、大小、方向进行操作,比如平移、缩放、旋转、反射等。…...

接口测试|超详细面试题【附答案】
今天给姐妹们整理了一套超详细的附答案的接口测试面试题,姐妹们快学起来吧~ 接口测试的重要性,相信不用我多说了。接口测试是现在软件测试工程师一个加分项。因为很多朋友一开始做了几年的软件测试都是在做功能测试,做界面UI的测试ÿ…...

Qt网络编程——QTcpServer和QTcpSocket
文章目录 核心APITCP回显服务器TCP回显客户端 核心API QTcpServer用于监听端口和获取客户端连接 名称类型说明对标原生APIlisten(const QHostAddress&, quint16 port)方法绑定指定的地址和端口号,并开始监听bind和listennextPendingConnection()方法从系统中获…...

CentOS 7 aarch64制作openssh 9.9p1 rpm包 —— 筑梦之路
本篇文章还是基于开源项目openssh-rpms制作。 https://github.com/boypt/openssh-rpms.git 官方发行说明: OpenSSH: Release Notes 1. 修改version.env 2. 下载源码包 openssl网站改版,下载地址和之前不一样了 # 下载openssl1.1.1w源码包cd downlo…...

Flink和Spark的区别
1、设计理念不同 flink:Flink是基于事件驱动的,是面向流的处理框架, Flink基于每个事件一行一行地流式处理,是真正的流式计算. 另外他也可以基于流来模拟批进行计算实现批处理。 spark:Spark的技术理念是使用微批来模拟流的计算,…...

以太网开发基础-MAC和PHY
直接参考: 以太网基础-MAC和PHY-CSDN博客 路由器上一般有三类MAC地址 给一个范例: 00:0C:E5:4B:F2:85 这个地址就可以作为LAN MAC地址 00:0C:E5:4B:F2:86 这个地址就可以作为WAN MAC地址 00:0C:E5:4B:F2:87 这个地址就可以作为无线 MAC地址 通常,路由器…...

Java 发布jar包到maven中央仓库(2024年9月保姆级教程)
文章目录 前言一、账号准备1. 注册登录账号2. 新建命名空间3. 验证命名空间4. 生成令牌5. 为 maven 设置令牌二、GPG准备1. 下载GPG2. 发布证书2.1 新建证书2.2 发布证书到服务器2.3 验证发布三、发布jar包到中央仓库1. 编辑项目pom文件2. 打包上传3. 发布jar包4. 搜索我们的ja…...

Pandas和Seaborn可视化详解
1.Pandas绘图-单变量 概述 pandas库是Python数据分析的核心库 它不仅可以加载和转换数据,还可以做更多的事情:它还可以可视化 pandas绘图API简单易用,是pandas流行的重要原因之一 可视化小技巧: 如果是类别型 柱状 饼图 (类别相对较少 5-…...

【Python】Windows下安装使用FFmpeg
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。之前为了MP3转wav,需要pip安装并import AudioSegment,但是会报错:FileNotFoundError: [WinError 2] 系统找不到指定的文件。 因为FFmpeg需要另…...

LLM - 使用 XTuner 指令微调 多模态大语言模型(InternVL2) 教程
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/142528967 免责声明:本文来源于个人知识与公开资料,仅用于学术交流,欢迎讨论,不支持转载。 XTuner…...

【Python】数据可视化之热力图
热力图(Heatmap)是一种通过颜色深浅来展示数据分布、密度和强度等信息的可视化图表。它通过对色块着色来反映数据特征,使用户能够直观地理解数据模式,发现规律,并作出决策。 目录 基本原理 sns.heatmap 代码实现 基…...

个人博客系统测试(selenium)
P. S.:以下代码均在VS2019环境下测试,不代表所有编译器均可通过。 P. S.:测试代码均未展示头文件stdio.h的声明,使用时请自行添加。 博主主页:Yan. yan. …...

【速成Redis】01 Redis简介及windows上如何安装redis
前言: 适用于:需要快速掌握redis技能的人(比如我),在b站,找了个课看。 01.课程简介_哔哩哔哩_bilibili01.课程简介是【GeekHour】一小时Redis教程的第1集视频,该合集共计19集,视频…...

入侵检测系统(IDS)和入侵预防系统(IPS)
入侵检测系统(IDS)和入侵预防系统(IPS)是网络安全领域中用来检测和防止潜在的恶意活动或政策违规行为的系统。它们的主要目的是保护网络和主机不受未授权访问和各种形式的攻击。以下是它们的主要区别和功能: 一&#…...

pytorch 加载模型参数后 如何测试数据,应用模型预测数据,然后连续变量转换成 list 或者numpy.array padans并保存到csv文件中
在PyTorch中,加载模型参数后测试数据通常涉及以下几个步骤: 1. **加载模型**:首先,你需要定义模型的结构,然后加载预训练的参数。 2. **加载数据**:准备你的测试数据集。确保数据集已经正确地预处理&…...

uni-app开发流程(开发、预览、构建和发布过程)
uni-app 是一个使用 Vue.js 开发所有前端应用的框架,支持编写一次代码,生成可以在多个平台(如微信小程序、H5、App等)运行的应用。下面是 uni-app 的开发流程,包括从创建项目到部署的各个阶段。 1. 创建项目 通过 HB…...

Linux Shell: 使用 Expect 自动化 SCP 和 SSH 连接的 Shell 脚本详解
文章目录 0. 引言2. 解决方案3. 脚本详解脚本1:使用 SSH 和 Expect 自动化登录远端机器脚本说明 脚本2:使用 SCP 和 Expect 自动化文件上传脚本说明 脚本3:使用 SCP 和 Expect 自动化文件下载脚本说明 4. 脚本的使用方法5. 关键技术点5.1. Ex…...

深入分析MySQL事务日志-Undo Log日志
文章目录 InnoDB事务日志-Undo Log日志2.1 Undo Log2.1.1 Undo Log与原子性2.1.2 Undo的存储格式1)insert类型Undo Log2)delete类型Undo Log3)update类型Undo Log 2.1.3 Undo Log的工作原理2.1.4 Undo Log的系统参数2.1.5 Undo Log与Purge线程…...

828华为云征文 | 在Huawei Cloud EulerOS系统中安装Docker的详细步骤与常见问题解决
前言 Docker是一种轻量级的容器技术,广泛用于应用程序的开发、部署和运维。在华为云的欧拉(Huawei Cloud EulerOS)系统上安装和运行Docker,虽然与CentOS有相似之处,但在具体实现过程中,可能会遇到一些系统…...
什么是数据增强中的插值法?
一、插值法的概念 在数据增强中,插值法是一种重要的技术,它通过数学模型在已知数据点之间估计未知数据点的值。这种方法可以帮助我们在不增加实际数据的情况下,通过生成新的数据点来扩展数据集。插值法基于这样的假设:如果已知的数…...

springboot实战学习(9)(配置mybatis“驼峰命名“和“下划线命名“自动转换)(postman接口测试统一添加请求头)(获取用户详细信息接口)
接着学习。之前的博客的进度:完成用户模块的注册接口的开发以及注册时的参数合法性校验、也基本完成用户模块的登录接口的主逻辑的基础上、JWT令牌"的组成与使用以及完成了"登录认证"(生成与验证JWT令牌)具体往回看了解的链接…...

之前做了抵押贷款,现在房市不景气,马上贷款要到期了该怎么办?
面对房贷的重压,特别是对于那些正承受高息贷款之苦的现有房产业主而言,探索有效的减负策略显得尤为重要。今天,我们共同探讨几种智慧策略,旨在帮助您巧妙减轻房贷的经济负担。 一、优化贷款结构:低息置换的魔力 当前&a…...

poi生成的ppt,powerPoint打开提示内容错误解决方案
poi生成的ppt,powerPoint打开提示内容错误解决方案 最近做了ppt的生成,使用poi制作ppt,出现一个问题。微软的powerPoint打不开,提示错误信息 通过xml对比工具发现只需要删除幻灯片的某些标签即可解决。 用的是XML Notepand 分…...

基于stm32物联网身体健康检测系统
在当今社会,由于经济的发展带来了人们生活水平不断提高,但是人们的健康问题却越来越突出了,各种各样的亚健康随处可在,失眠、抑郁、焦虑症,高血压、高血糖等等侵袭着人们的健康,人们对健康的关注达到了一个…...

BeautifulSoup4在爬虫中的使用
一、Beautiful Soup4简介 Beautiful Soup 提供一些简单的python函数来处理导航、搜索等功能。 它是一个工具箱,是python的一个库,最主要的功能是从网页获取数据。 二、Beautiful Soup4安装 在cmd下安装 pip install beautifulsoup4三、BeautifulSou…...

Laya2.x出包alipay小游戏
小游戏开发者工具,支付宝官方已经出了,不说了。 1.LAYA2.X打出得小游戏包中my-adapter.js这个文件需要替换,或者自行修改,替换3.x得; 2.unity导包出得模型文件命名需要注意,避免太长,路径也不…...

Vue极简入门
1.注册路由,如果是子路由,就加一个children import Vue from vue import Router from vue-router import Main from ../views/Main.vue import Login from ../views/Login.vueimport UserProfile from "../views/user/Profile.vue" import Us…...

系统敏感信息搜索工具(支持Windows、Linux)
目录 工具介绍 使用说明 search模块 browser模块 下载地址 工具介绍 可以快速搜索服务器中的有关username,passsword,账号,口令的敏感信息还有浏览器的账户密码。 使用说明 search模块 searchall64.exe search -p 指定路径 searchall64.exe search -p 指定路径 -s &q…...