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

news2024/12/23 9:45:10

目录

前言

一.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()可以提高插入数据的效率,避免增容带来的开销。相当实用!

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

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

相关文章

分组密码模式的填充

分组加密 在密码学中&#xff0c;分组加密(Block cipher)&#xff0c;又称分块加密或块密码&#xff0c;是一种对称密钥算法。 它将明文分成多个等长的模块(block)&#xff0c;使用确定的算法和对称密钥对每组分别加密解密。 常见的分组加密算法有: DES、3DES、AES、IDEA。 …

Ubuntu虚拟机部署配置

目录 虚拟机镜像下载 VirtualBox7下载 VirtualBox7安装镜像流程 创建虚拟机 虚拟机挂单独硬盘 网络设置 检查虚拟机配置 启动虚拟机 ubuntu配置 查询虚拟机IP地址 修改ROOT密码 更新apt NTP同步 挂载磁盘&关闭swap 虚拟机镜像下载 目前国内操作系统镜像源非常…

2023-07-19力扣今日二题

链接&#xff1a; 2737. 找到最近的标记节点 题意&#xff1a; 给一个n节点有向图&#xff0c;求节点s和点集marked中的最短距离&#xff0c;没有可以的到达的点则返回-1 解&#xff1a; 摇了一题困难过了2/3&#xff0c;搞不定了 没有负权边的单源最短距离&#xff0c;迪…

代码-【2 单链表A、B交集存放到C】

1&#xff09;基本思想&#xff1a; A、B两个链表的元素均递增有序&#xff0c;所以可以按顺序&#xff0c;同时从A中和B中各取一个结点的值来对比&#xff1b;如果A中结点的值比较小&#xff0c;则A中的指针右移&#xff1b;如果B中的结点的值比较小&#xff0c;则B中的指针右…

优思学院|工程师学习六西格玛有什么用?

很久以前&#xff0c;世上没有当今盛行的各种简单易用的统计软件&#xff0c;那时复杂的统计分析只能依靠公司的统计顾问。而和他们在一起工作时&#xff0c;工程师必须知道怎样进行提问。 如果工程师缺乏对统计工具的认识&#xff0c;即使拿到正确的工具也于事无补。当顾问遇…

2. Makefile之目标、依赖(附示例)

一、本节概要 本专栏所有内容围绕Makefile官方文档进行刨析&#xff0c;给出详细具体示例做辅助理解手撕Makefile官方手册 二、Makefile中的目标和依赖 在一个简单的Makefile中&#xff0c;每条规则通常由以下几个部分组成&#xff1a; target ... : prerequisites ...rec…

修改虚拟机ip为静态ip

在使用虚拟机的时候&#xff0c;默认情况下使用的DHCP协议分配的动态IP地址&#xff0c;使得每次打开虚拟机后当前的IP地址都可能会发生变化&#xff0c;这样不方便管理。为了能够给当前虚拟机设置一个静态IP地址&#xff0c;方便后期使用XShell等连接工具进行连接&#xff0c;…

C/C++内存分布

C/C内存管理 1.C/C内存分布2.C语言中动态内存管理方法2.1 malloc/calloc/realloc/free 3.C内容管理方法3.1new/delete操作内置类型3.2 new和delete操作自定义类型 4.operator new与operator delete函数5.new和delete的实现原理5.1内置类型5.2自定义类型 6定位new表达式&#xf…

Libtorch 在x86_64的Linux 上部署时的版本问题

1. ubuntu 上安装了cuda12.1 和cuda 12.2 ,但是NVCC 指向的是10.1&#xff0c;但是10.1 又没有安装&#xff0c; 所以版本很混乱 ./usr/bin/nvcc -> 10.1./usr/lib/nvidia-cuda-toolkit/bin/nvcc-> 10.1./usr/local/cuda-12.1/bin/nvcc -> 12.1./usr/local/cuda-12.2…

RT-Thread快速入门-线程管理

在 RT-Thread 中&#xff0c;最基本的调度单位是线程&#xff0c;其他 RTOS 也叫任务。如果学习过或者了解过 RTOS&#xff0c;任务这种叫法是最为熟知的。 本篇文章来学习一下 RT-Thread 线程方面的内容。对于初学者来说&#xff0c;转换一下思维&#xff0c;建立多任务&…

Docker部署Redis集群详解【主从复制 + 哨兵模式】

前言 注意&#xff1a;该文章不会讲解Redis集群搭建的原理&#xff0c;只讲述如何通过Docker容器快速部署搭建Redis主从 哨兵模式的集群 准备工作&#xff1a; 一台云服务器 or 本地虚拟机&#xff08;CentOS和Ubuntu都可以&#xff09;安装好Docker环境&#xff08;Docker、…

ROS框架——发布者功能包和订阅者功能包进行bool类型数据结构的topic通讯

ROS框架——发布者功能包和订阅者功能包进行bool类型数据结构的topic通讯 code review! 文章目录 ROS框架——发布者功能包和订阅者功能包进行bool类型数据结构的topic通讯零.同时运行两个功能包一.发布者功能包1.1.文件结构1.2.bool\_publisher\_node.cpp1.3.CMakeLists.txt…

SpringBoot实战(二十一)集成 TLog 日志

目录 一、简介二、Maven依赖三、启动类集成四、测试1.服务简介2.服务A代码DemoController.javaDemoFeignClient.java 3.服务B代码4.测试结果 补充一&#xff1a;自定义日志标签模板补充二&#xff1a;SpanId的生成规则补充三&#xff1a;业务标签1.打印入参2.指定连接符3.打印常…

【深度学习-卷积神经网络CNN-基础】

文章目录 发展历史卷积神经网络的应用领域卷积的原理和作用卷积和传统的神经网络的区别 卷积网络的整体架构输入层卷积层池化层全连接层卷积和池化叠加多层卷积可以处理什么类型的数据卷积的超参数卷积最大的优势 卷积的细节卷积的原理卷积的参数卷积的次数步长 卷积核尺寸 边缘…

成为UI设计高手:如何规划和创建UI设计组件库!

今天给大家分享一篇关于组件化设计的总结&#xff0c;希望可以带给大家更多设计思考。 什么是组件化 组件化化是构成界面的最基础元素和重复出现控件的集合体&#xff0c;也就是常说的组件库。通过对基础元素和控件的规范命名与排列组合&#xff0c;最终形成一个可快速调用与便…

每日一题——地下迷宫(迷宫问题II)

迷宫问题&#xff08;地下迷宫&#xff09;——II 题目链接 前言&#xff1a; 这题是在昨天迷宫问题——I的基础上进行的变形&#xff0c;因此&#xff0c;如果昨天的题目没看或者对迷宫问题不怎么了解&#xff0c;建议先看看昨天的解析。 迷宫问题——I源代码&#xff1a; …

安装redis,适配阿里云服务器,Liunx安装redis

下载redis以及编译安装 下载redis文件 wget http://download.redis.io/releases/redis-6.0.8.tar.gz #下载redis压缩文件 tar xzf redis-6.0.8.tar.gz #解压缩 cd redis-6.0.8 make 查看是否安装了gcc编译输入gcc --version如果没有…

AtcoderABC236场

A - chukodaiA - chukodai 题目大意 题目要求交换字符串S中第a个字符和第b个字符的位置&#xff0c;并输出结果。 思路分析 借用临时变量t&#xff0c;进行记录交换。 时间复杂度 O(∣S∣) 输出交换后的字符串的时间复杂度为O(∣S∣)&#xff0c;其中∣S∣表示字符串SS的…

autohotkey实战:窗口透明化

文章目录 实现方法代码讲解WinGet和WinSet 注 本文采用的是V1版本语法 实现方法 窗口透明不仅实用性强&#xff0c;关键是非常炫酷&#xff0c;如果用AHK实现一个实时调节窗口透明度的工具&#xff0c;那么就可以一边敲代码&#xff0c;一边透过半透明的IDE&#xff0c;愉快地…

vue 3.0 如何实现 文本框只能输入数字 避免文字和符号

<input v-model.number"form.payTime" :min"0" type"number" οninput"valuevalue.replace(/[^0-9.]/g,)" type"text" /> v-model 后面的.numer 一定要加上不然没效果 οninput"valuevalue.replace(/[^0-9.]/g…