STL——String类(2)成员函数详解

2023-11-03

目录

前言

一.String的成员函数:

1.基本成员函数

代码实验:

 实验结果:

类对象每次扩容后的capacity数据展示:

1.2. resize():调整字符串大小

1.3reserve():请求更改该对象的容量capacity值

代码实验:


       

前言

        String是第一个我们在C++道路上要学习的STL容器,在上篇博客中,我们也已经大概的了解到了String类的由来——由于C语言中char类型的数组、字符串用的不够方便,所以创建了String类,之后就是学习了该类对象的创建方式和多种遍历方法,感兴趣的小伙伴们可以去看看:( C++之STL——String字符序列类(1)

        那么在本文中,我们将继续学习有关String类的成员函数!

一.String的成员函数:

1.基本成员函数

        其实,String类的底层是用的顺序表的形式实现的,物理结构上是一段连续的存储空间——数组,只不过这个数组只用于存储字符内容,所以该类并没有模板!既然是数组,那肯定有空间大小、空间的使用情况、最大容量等属性,那么为了体现类的封装性,设计者将这些基本属性都进行封装成了成员函数:

size() / length()——获取String类对象当前数据的总个数 ;

max_size()——      获取String类对象所能存放数据最大容量,单位是个数

resize()——用于调整类对象的_size数据,这个会针对_size和形参做多种情况的处理

capacity()——获取String类对象当前容量的大小

reserve()——用于扩大类对象的存储容量,是一个常用的函数。

clear()——对String类对象的数据内容清空(注:只清理数组的size,不清理数组的capacity)

empty()——判断该数组当前是否为空

shrink_to_fit——使该对象的容量(capacity)和大小(size)相等,相当于缩小容,缩容是用时间换取空间,创建一块新空间,用新空间代替旧空间。所以该函数几乎不用。

代码实验:

#include<iostream>
using namespace std;

int main() {
    string s1;
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	cout << s1.capacity() << endl;
	cout << s1.max_size() << endl;
	cout << s1.empty() << endl;	

	cout << "--------------------" << endl;


    string s2 = "Hello World!!!!!!";
	cout << s2.size() << endl;
	cout << s2.length() << endl;
	cout << s2.capacity() << endl;
	cout << s2.max_size() << endl;
	cout << s2.empty() << endl;
	cout << "--------------------" << endl;
    s2.clear();	//清空
	cout << endl;
	cout << s2.size() << endl;			//size和length功能相同
	cout << s2.length() << endl;
	cout << s2.capacity() << endl;		//判断容量,若超出容量则该函数会自动扩容
	cout << s2.max_size() << endl;		//最大字符量:21亿多
	cout << s2.empty() << endl;
	cout << "-----------------" << endl;
    return 0;
}

 实验结果:

        结果分析:通过上图代码演示:String类对象s1初始化就为空,而类对象被创建的那一刻,底层数组会默认被分配15个字节大小的容量,该数组默认的最大容量有21亿字节之多。

        相比较有内容的s2对象,它的初始化内容就超出了底层默认给出的15字节,那么String类会自动为该对象进行扩容。通过clear()函数的使用,我们印证了使用clear,并不会清理s2的capacity,它的值仍然为31,只是size被清理为了0。

类对象每次扩容后的capacity数据展示:

void Test1(){
    string s;				//创建空字符串
    size_t sz = s.capacity();	//获取字符串的容量
    cout << s.capacity() << endl;
    cout << "making s grow:\n";
    for (int i = 0; i < 100; ++i){
	    s.push_back('c');	//在for中插入数据字符c一百次
	    if (sz != s.capacity()){
		    sz = s.capacity();
		    cout << "capacity changed: " << sz << '\n';
	    }
    }
}

         通过结果可知:默认情况下都是15字节大小的容量,而每当我们为该对象增加数据超过其容量时,会触发底层扩容机制,该对象的capacity会进行1.5——2倍左右的容量增大。

注:这只是VS编译器下的扩容机制,在其他平台下可能会有所不同!


在这些基本函数中,最重要的是resize()和reserve():

1.2. resize():调整字符串大小

        resize()有两种用法,一种只是调整该对象字符串的大小,还有一种是在调整的基础上,设定剩余空间的内容数据。 一般情况下,只要不加第二参数,默认用的是void resize(size_t n);

         该函数说白了就是把类对象存储的字符串大小调整为 n 个字符的长度。

       1. 如果第一参数n设定的值小于当前字符串长度,则当前值将缩短为其第一个 n 个字符,删除第 n 个字符以外的字符;

       2.  如果 n 大于当前字符串长度,则通过在末尾插入所需数量的字符以达到 n 大小来扩展当前内容。此外resize()有第二个参数c,如果指定了 c,则新元素初始化为 c 的副本,否则,它们是值初始化字符(空字符)。

情况1: 

int main(){
	string ss1 = "Hello World";    //共11个字符大小

	//情况1:当n<size(字符串的当前长度)时:数据被删,且size缩小
	ss1.resize(5);			//n==5,仅保留字符串的前5个字符
	 cout << ss1 << endl;	//那么ss1=="Hello",size会被改变,该字符串被删除部分数据
	 cout << ss1.size() << endl;
	 cout << ss1.capacity() << endl;
	 cout << "----------------------------" << endl;


	 ss1 = "Hello World";
	 //情况2:当size<n<=15(capacity首次的容量)时:该字符串会被增加数据,容量不变
	 ss1.resize(15);			//n==15,字符串大小为11,会全部被保存,但还剩4个字符,那么都为'\0'
	 cout << ss1 << endl;		//那么ss1=="Hello World    ",size会被改变,
	 cout << ss1.size() << endl;
	 cout << ss1.capacity() << endl;	//不变
	 cout << "----------------------------" << endl;

}

 

        ss1="hello world"; 对ss1使用resize(5)后,意味着ss1的字符串内容变为了"hello",强行删减了ss1的数据内容—— n< size。

//情况3:当n>15(capacity首次的容量)时:该字符串会被增加数据+容量也被扩大   
     ss1 = "Hello World";
	 ss1.resize(25,'h');			//n==25,字符串大小为11,会全部被保存,剩下的字符全部用字符h代替
	 cout << ss1 << endl;		//那么ss1=="Hello World    ",不仅size会被改变,capacity也会变,
	 cout << ss1.size() << endl;
	 cout << ss1.capacity() << endl;

        ss1的大小为11,resize设定的n值为25,25大于11,则发生扩容,且该字符串由于使用了resize函数的第二参数,所以"hello world"后面的内容全部赋值为字符h。 


1.3reserve():请求更改该对象的容量capacity值

reserve在英文中的意思为:存储、保留。

        函数的具体含义:请求使字符串容量适应计划的大小更改为最多 n 个字符。

        如果 n 大于当前字符串容量,则该函数会导致容器将其容量增加到 n 个字符(或更大)。

        在其他情况下,收缩字符串容量被视为非约束性请求:容器实现可以自由优化,否则,字符串的容量大于 n。
        注:此函数对字符串长度size没有影响,并且无法更改其内容。

        说白了该函数就是用来扩容的!

代码实验:
int main(){
    string ss2 = "Made In China!";

	ss2.reserve(50);	
	cout << ss2.size() << endl;
	cout << ss2.capacity() << endl;

	ss2.reserve(100);    //
	cout << ss2.size() << endl;
	cout << ss2.capacity() << endl;
    return 0;
 }

结果: 

        为ss2字符串扩充容量50字节,由于ss2的size为14,capacity为15,扩容50后从15-->63字节大小,再次扩容后从63-->111字节,从中可以发现:ss2的size始终没变。

        注:如果该对象的capacity为100,使用reserve(5),并不会导致capacity缩容!

        设计reserve函数的原因就是因为我们之前在写顺序表等数据结构在堆区扩容的时候,会有代价(时间或空间上的代价);而使用reserve不会有空间上或时间上的浪费,利用reserve()可以提高插入数据的效率,避免增容带来的开销。相当实用!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

STL——String类(2)成员函数详解 的相关文章

  • 结构化绑定中缺少类型信息

    我刚刚了解了 C 中的结构化绑定 但有一件事我不喜欢 auto x y some func is that auto正在隐藏类型x and y 我得抬头看看some func的声明来了解类型x and y 或者 我可以写 T1 x T2 y
  • 如何将 std::string& 转换为 C# 引用字符串

    我正在尝试将 C 函数转换为std string参考C 我的 API 如下所示 void GetStringDemo std string str 理想情况下 我希望在 C 中看到类似的东西 void GetStringDemoWrap r
  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • C# 动态/expando 对象的深度/嵌套/递归合并

    我需要在 C 中 合并 2 个动态对象 我在 stackexchange 上找到的所有内容仅涵盖非递归合并 但我正在寻找能够进行递归或深度合并的东西 非常类似于jQuery 的 extend obj1 obj2 http api jquer
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • C# 中的 IPC 机制 - 用法和最佳实践

    不久前我在 Win32 代码中使用了 IPC 临界区 事件和信号量 NET环境下场景如何 是否有任何教程解释所有可用选项以及何时使用以及为什么 微软最近在IPC方面的东西是Windows 通信基础 http en wikipedia org
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri

随机推荐

  • RocketMQ系列之顺序消费

    前言 上节我们介绍了RMQ的两大亮点 重试和重复消费的问题 其实重试才能算亮点 重复消费最终还是要由我们自己来解决这个问题 RMQ自身并没有提供很好的机制 至少目前是没有 不知道将来会不会有 OK扯远了 今天呢 我们再来介绍RMQ一个不错的
  • 程序员接单当渠道

    接单之前 先简单说一下接私活的几种项目类型 之后直接上渠道 你可以对照着去找项目 程序员兼职主要分为三种 项目外协 项目整包和自由职业者驻场 所谓的项目外协 指的是需求方这边有自有工程师配合 只需要某个职位的工程师开发某个模块的项目 比如开
  • 股票入门浅学20210721

    A股 港股 美股 无论是上证50 还是沪深300都不能代表中国 我投资的是中国公司 不是A股公司 A股牛市更强更猛 这个时候适合投资A股 港股介于美股和A股之间 上市公司多为大企 市场机制更适合打新 美股十年牛市 是最适合股票投资的市场 总
  • 实战DeviceIoControl 之五:列举已安装的存储设备

    Q 前几次我们讨论的都是设备名比较清楚的情况 有了设备名 路径 就可以直接调用CreateFile打开设备 进行它所支持的I O操作了 如果事先并不能确切知道设备名 如何去访问设备呢 A 访问设备必须用设备句柄 而得到设备句柄必须知道设备路
  • 手撕BOOST

    原文链接 https mp weixin qq com s biz Mzk0NjIxODM3Mg mid 2247486612 idx 1 sn b3d95c6403c31738324e68e71a85268b chksm c308387f
  • 【面试八股文】每日一题:谈谈你对设计模式的理解

    谈谈你对设计模式的理解 每日一题 设计模式 谈谈你对设计模式的理解 面试八股文 设计模式 Design pattern 是一套被反复使用 多数人知晓的 经过分类编目的 代码设计经验的总结 通过对这些设计模式的合理使用能够是我们的系统更加的健
  • 【APP测试基础】第二篇

    安装与卸载安全性 应用程序应能正确安装到设备上 能够在安装设备上找到应用程序的相应图标 是否包含数字签名信息 安装路径应能指定 没有用户的允许 应用程序不能预先设定自动启动 卸载是否安全 其安装进去的文件是否全部卸载 卸载用户使用过程中产生
  • 几种页面重定向代码

    方法一 对于HTML语言 以下是代码片段 Loading 对于HTML语言可以用如上方法 以上含义为 则会在2秒之后重定向到 http www 你的域名 com 如果 http www 你的域名 com为本身 则每2秒自动刷新1次 如果 c
  • ECharts大屏可视化

    文章目录 ECharts大屏可视化 一 项目概述 1 1 项目介绍 1 2 项目架构 1 3 使用环境 二 数据获取 1 获取腾讯数据 1 1数据爬取 1 2数据存储 创建数据库 连接数据库 插入和更新数据 2 爬取百度热搜数据 2 1数据
  • 使用tps5430制作正负DC-DC降压电源,tps7a47和tps7a33制作正负LDO线性电源

    今天 小刚我制作了一款DC DC和LDO线性电源 其输入范围为10V 35V 配置4个电源输出端分别为 开关电源tps5430 正负12V 正负5V LDO线性电源tps7a47和tps7a33 正负5V 正负3 3V 第一部分TPS543
  • 飞桨AI套件首秀:新版PaddleX精选模型产业落地实战

    近日 飞桨AI套件PaddleX 精选产业实用模型的一站式开发套件正式上线AI Studio星河社区 也发布了 Windows 本地端 助力人工智能技术在各领域的实际应用 PaddleX具有优质的算法库 便捷的开发方式 高效的模型部署 丰富
  • pass软件计算样本量_R语言元分析专题第十五章:计算效应量的大小

    尽管通过meta软件包调用metabin或metacont函数 可以计算出每个研究中的个体效应大小 individual effect sizes 但一些论文却没有以正确的格式报告这些效应量数据 特别是 一些较老的文章可能只报告了t检验 A
  • c++学习之c++对c的扩展1

    目录 1 面向过程与面向对象的编程 2 面向对象编程的三大特点 3 c 对c的扩展 1 作用域运算符 2 命名空间 1 c 命名空间 namespace 2 命名空间的使用 1 在不同命名空间内可以创建相同的名称 2 命名空间只能在全局范围
  • 【QT学习】结构体在qt的传递

    1 自定义结构体使用信号槽在qwidget中传递 typedef struct tagPoint tPos tIn QHash
  • 通达信缠论完整指标_【画线参数调整、拔地而起指标介绍、走势完美实战案例】疯狂的缠论通达信版自动画线选股指标更新:很小但很有用的更新...

    导读 文章包含4部分 通达信版画线选股指标的画线参数都可以手动调整了 通达信版画线选股指标子指标介绍 拔地而起 走势完美策略实战案例 走势完美策略实战要点 理论 1 通达信版自动画线选股指标更新 画线参数都可以手动调整 疯狂的缠论通达信版自
  • Java 实现图片转base64

    一 自己实现byte数组拷贝 public class Base64Util base64图片 存储的byte数组 private byte baseByte new byte 0 public static void main Strin
  • Skill: UltraEdit: ue64ctmn.dll 删除不掉

    卸载UltraEdit时ue64ctmn dll删除不掉 原因 自动生成鼠标右键菜单项 该文件被鼠标右键menu占用 解决 在运行中输入 regedit 展开 HKEY CLASSES ROOT shellex ContextMenuHan
  • 基于uniapp实现掘金的微信小程序模版小项目

    代码地址 1 前言 涉及的框架及技术 uniapp vant animate vuex iconfont websocket 2 启动流程 直接用Hbuilder打开 然后点击运行 gt 运行到小程序模拟器 gt 微信开发者工具 启动之后如
  • 用AI写代码 -- Github Copilot测试

    截图为copilot官网 要使用copilot 首先要安装vscode 下载copilot插件 下载完了以后 并不能马上使用 还需要申请内测账号 前几天 我终于收到内测账号通过的邮件 趁着今天在家 连忙打开vscode测试一下 爬图片 我们
  • STL——String类(2)成员函数详解

    目录 前言 一 String的成员函数 1 基本成员函数 代码实验 实验结果 类对象每次扩容后的capacity数据展示 1 2 resize 调整字符串大小 1 3reserve 请求更改该对象的容量capacity值 代码实验 前言 S