C++奇迹之旅:string类对象的容量操作

请添加图片描述

文章目录

  • 📝 string类的常用接口
  • 🌉 string类对象的容量操作
    • 🌠size
    • 🌠length
    • 🌠capacity
    • 🌠clear
    • 🌠empty
    • 🌠reserve
    • 🌉resize
  • 🚩总结


📝 string类的常用接口

string网址查询:https://legacy.cplusplus.com/reference/string/string/

🌉 string类对象的容量操作

在这里插入图片描述

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

🌠size

  1. size—》返回字符串的长度(以字节为单位)。
size_t size() const;

在这里插入图片描述

string str("hello C++");
cout << "The size of str is " << str.size() << endl;

在这里插入图片描述

🌠length

  1. length—》返回字符串的长度(以字节为单位)
size_t length() const;

在这里插入图片描述

string str2("hello string");
cout << "The lenth of str2 is " << str2.length() << endl;

在这里插入图片描述

string::sizestring::length 是同义词,返回完全相同的值。

🌠capacity

  1. capacity---->返回当前为字符串分配的存储空间的大小,以字节表示。
size_t capacity() const;

在这里插入图片描述
之所以 str.capacity() 的值是 15,是因为 C++ 标准库在创建字符串时会分配一些额外的内存空间来应对未来可能的字符串增长。这个额外的内存空间被称为 “预留空间”。

字符串 "hello C++"10 个字符,但是 C++ 标准库在创建这个字符串时会分配 15 个字符的内存空间。这样可以避免频繁的内存重新分配操作,提高性能,所以 str.capacity() 的值是 15

🌠clear

  1. clear–》擦除字符串的内容,该字符串将变为空字符串(长度为 0 个字符)。
void clear();

clear擦除字符串的内容,该字符串将变为空字符串,长度为0,但是存储空间没有改变

int main()
{string s1("hello C++");cout << s1 << endl;s1.clear();cout << s1 << endl;cout << s1.size() << endl;cout << s1.capacity() << endl;return 0;
}

在这里插入图片描述

🌠empty

  1. empty–》返回字符串是否为空(即其长度是否为 0)
    此函数不会以任何方式修改字符串的值。若要清除字符串的内容,请看string::clear
bool empty() const;

如果字符串长度为 0,则为 true,否则为 false

int main()
{string str1;// 创建一个空字符串string str2 = "Hello, world!"; // 创建一个非空字符串if (str1.empty()){cout << "str1 is empty." << endl;}else{cout << "str1 is not empty." << endl;}if (str2.empty()) {std::cout << "str2 is empty." << std::endl;}else {std::cout << "str2 is not empty." << std::endl;}return 0;
}

在这里插入图片描述

🌠reserve

  1. reserve —》为字符串预留空间
    std::string::reserve()std::string 类的一个成员函数,用于预先分配内存空间,以提高字符串的性能。

当你需要向字符串中添加大量字符时,使用 reserve() 函数可以避免频繁的内存分配和拷贝操作,从而提高程序的性能。

int main()
{string str;//不使用reservefor (int i = 0; i < 1000000; i++){str += 'a';}cout << "size: " << str.size() << ",Capacity: " << str.capacity() << endl;//使用reserve()string str2;str2.reserve(1000000);for (int i = 0; i < 1000000; i++){str2 += 'a';}cout << "size: " << str2.size() << ",Capacity: " << str2.capacity() << endl;return 0;
}

可以看到,在使用 reserve() 函数的情况下,str2 的容量(capacity)与大小(size)相同,而在不使用 reserve() 函数的情况下,str 的容量大于其大小。这就是 reserve() 函数的作用:它可以预先分配内存空间,避免频繁的内存分配和拷贝操作,从而提高程序的性能。
在这里插入图片描述

str2.reserve(10);//容量不足会怎么样?

在这里插入图片描述

当你将 str2.reserve(10) 设置的容量远小于实际需要的容量,输出结果也会显示 Capacity: 1170118。这是因为 std::string 的内部实现机制。
当你使用 reserve() 函数时,它会尝试分配指定大小的内存空间。但是,如果实际需要的空间大于指定的空间,std::string 会自动增加内存空间,以满足实际需求。这个过程称为"内存重新分配"。
即使只预留了 10 个字符的空间,但当你向 str2 添加 1,000,000 个字符时,std::string 会自动增加内存空间,以容纳所有的字符。这就是为什么最终的容量会大于 1,000,000 的原因。
std::string 的容量通常会比实际需要的空间大一些,这是为了提高性能。当需要添加新的字符时,不需要频繁地重新分配内存,从而避免了内存拷贝的开销。

  • 增长策略:
    当向 std::string 添加字符时,如果当前容量不足,标准库会自动分配一个更大的内存块。增长策略通常是以当前容量的 2 倍或 1.5 倍来扩展容量,以减少内存重新分配的次数。
//利用reserve提高插入数据的效率,避免增容带来的开销
void TestPushBack()
{string s;size_t sz = s.capacity();cout << "making s grow:\n";for (int i = 0; i < 100; ++i){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed: " << sz << '\n';}}
}
  • 构建vector时,如果提前已经知道string中大概要放多少个元素,可以提前将string中空间设置好
void TestPushBackReserve()
{string s;s.reserve(100);size_t sz = s.capacity();cout << "making s grow:\n";for (int i = 0; i < 100; ++i){s.push_back('c');if (sz != s.capacity()){sz = s.capacity();cout << "capacity changed: " << sz << '\n';}}
}

🌉resize

  1. resize —》用来改变 std::string 对象的大小
    两种语法:
void resize (size_t n);
void resize (size_t n, char c);

在这里插入图片描述

  • 第一种形式的 resize() 函数会将 std::string 的大小设置为 n 个字符,并用默认值 (通常是 '\0') 填充新增的字符。
void resize (size_t n);

例子:

string str = "Hello, world!";
cout << "size: " << str.size() << ",Capacity: " << str.capacity() << endl;
str.resize(20);
cout << "size: " << str.size() << ",Capacity: " << str.capacity() << endl;

在这里插入图片描述
可以看出:与 reserve() 函数不同,resize() 函数不仅改变了 std::string 的容量,还改变了它的大小。这意味着,调用 resize() 函数后,std::stringsize()capacity() 函数返回的值都会发生变化。

  1. 将字符串大小设置为 20 个字符,并用字符 'x' 填充新增的部分
string str = "Hello, world!";
str.resize(20, 'x');
cout << str << endl;

在这里插入图片描述

  1. 将字符串大小缩小到 5 个字符:
	string str = "Hello, world!";str.resize(20, 'x');cout << str << std::endl;

注意:如果 n 小于当前 std::string 的大小,则 resize() 函数会截断字符串,删除超出部分的字符。如果 n 大于当前 std::string 的大小,则 resize() 函数会扩展字符串,并用指定的字符填充新增的部分。
在这里插入图片描述


🚩总结

  1. size()length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一
    致,一般情况下基本都是用size()
  2. clear()只是将string中有效字符清空,不改变底层空间大小。
    请添加图片描述

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

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

相关文章

JavaScript进阶2

自定义对象 let 自定义对象名{ 属性名:属性值, 函数名称:function(形参列表){} }; 注意&#xff1a;在自定义对象中使用当前自定义对象的属性或者函数&#xff0c;需要使用this <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-…

PMP有效期三年后,还有必要续证吗?

通常情况下是必要的&#xff0c;续证条件是在3年内累积60个PDU和支付150美元。如果到期后没有进行续证&#xff0c;但仍希望保持证书&#xff0c;就需要重新参加PMP考试。重新参加考试的费用包括3900元的报名费和数千元的培训费。因此&#xff0c;与重新考试相比&#xff0c;续…

面向过程和面向对象

面向过程和面向对象的概念及区别 面向过程&#xff1a; 概念&#xff1a; 面向过程是一种以事件为中心的编程范式。它按照功能将程序结构划分为若干个基本模块&#xff0c;形成树状结构。每个模块内部一般由顺序、选择和循环三种基本结构组成。 特点&#xff1a; 程序流程在编…

实现ApplicationContextAware接口完成springboot项目的初始化处理工作

需求&#xff1a;在项目启动的时候&#xff0c;从数据库里取出所有敏感词&#xff0c;放到map里面。 ApplicationContextAware 的实现类的setApplicationContext方法可以获取到IOC容器&#xff0c;虽然这个案例里面并没有什么用&#xff0c;但是项目初始化一般实现ApplicationC…

C++中rand()函数和随机数种子

C中rand()函数的用法 rand() % (b-a1) a ; 就表示 a~b 之间的一个随机整数。 表达式 int num rand() % 100 1; 产生的是1到100之间的随机数&#xff0c;而不是1到99。 rand() % 100 会产生一个从0到99的随机数&#xff0c;因为 % 是取模运算符&#xff0c;它会给出 rand() …

【算法刷题day49】Leetcode:123.买卖股票的最佳时机III、188. 买卖股票的最佳时机 IV

文章目录 Leetcode 123.买卖股票的最佳时机III解题思路代码总结 Leetcode 188. 买卖股票的最佳时机 IV解题思路代码总结 草稿图网站 java的Deque Leetcode 123.买卖股票的最佳时机III 题目&#xff1a;123.买卖股票的最佳时机III 解析&#xff1a;代码随想录解析 解题思路 定…

【AI】人工智能的应用及挑战

AI是人工智能&#xff08;Artificial Intelligence&#xff09;的缩写&#xff0c;它是一种模拟人类智能的技术和系统&#xff0c;旨在使计算机能够模仿人类的思维、学习、推理、理解自然语言&#xff0c;并能执行各种任务。AI利用大数据、机器学习、模式识别、自然语言处理等技…

通过 Java 操作 redis -- 基本通用命令

目录 使用 String 类型的 get 和 set 方法 使用通用命令 exists &#xff0c;del 使用通用命令 keys 使用通用命令 expire,ttl 使用通用命令 type 要想通过 Java 操作 redis&#xff0c;首先要连接上 redis 服务器&#xff0c;推荐看通过 Java 操作 redis -- 连接 redis 关…

思维导图在线怎么制作?推荐这些工具

思维导图在线怎么制作&#xff1f;在如今的快节奏时代中&#xff0c;思维导图作为一种高效的信息组织与思考工具&#xff0c;受到了广泛的应用。在线制作思维导图成打破了时间和空间的限制&#xff0c;使得团队协作变得更加便捷&#xff0c;个人创作也更为灵活。以下是四款备受…

建模电梯的状态图和学生选课ER图

第一题 尝试建模电梯的状态图&#xff08;选做&#xff09; 第二题 学校规定&#xff1a; 一个学生可选修多门课&#xff0c;一门课有若于学生选修。 一个教师可讲授多门课&#xff0c;一门课只有一个教师讲授。 一个学生选修一门课&#xff0c;仅有一个成绩。 学生的属性有学号…

JS中的arguments是什么?

arguments是当我们不确定有多少个参数传递时&#xff0c;就可以使用argument来获取。在js中&#xff0c;arguments实际上就是当前函数的一个内置对象&#xff0c;存储了我们传递的所有实参。arguents的展示形式就是一个伪数组&#xff0c;所以我们可以对它进行遍历。 我们先来…

机器学习-监督学习

监督学习是机器学习和人工智能中的一个重要分支&#xff0c;它涉及使用已标记的数据集来训练算法&#xff0c;以便对数据进行分类或准确预测结果。监督学习的核心在于通过输入数据&#xff08;特征&#xff09;和输出数据&#xff08;标签或类别&#xff09;之间的关系&#xf…

基于Python的飞机大战游戏

学习目标 了解 飞机大战游戏的规则 理解 面向对象思想,会独立设计游戏的类与模块 掌握 pygame模块的使用 1.1 游戏介绍 飞机大战是一款由腾讯公司微信团队推出的软件内置的小游戏,这款游戏画面简洁有趣,规则简单易懂,操作简便易上手,在移动应用兴起之初曾风靡一时。 1.1.…

使用YOLOv8 YOLOv5 进行距离测量,速度测量。使用目标检测进行测距,测速是如何实现的呢?

文章大纲 简介差帧算法(Frame Difference Algorithm)目标检测测距使用YOLOv8 进行测距代码样例代码原理目标检测测速使用YOLOv8 进行测速代码原理参考文献综述简介 导读 在精确检测车速车距的方案中,视觉方案是非常具有挑战性的,但由于没有昂贵的距离传感器而大幅降低成本…

oracle 9i 行头带有scn的表

oracle 9i 行头带有scn的表 conn scott/tiger drop table t1; drop table t2; create table t1(c varchar2(5)); create table t2(c varchar2(6)) ROWDEPENDENCIES; --t2表每行都有scn,会增加六个字节的开销 alter table t1 pctfree 0; alter table t2 pctfree 0; insert in…

WordPress原创插件:超链接点击访问统计

WordPress原创插件&#xff1a;超链接点击访问统计 https://download.csdn.net/download/huayula/89296775

【Ajax零基础教程】-----第四课 简单实现

一、XMLHttpRequest对象 通过XMLHttpRequest对象来向服务器发送异步请求&#xff0c;从服务器获取数据。然后用JavaScript来操作DOM而更新页面。XMLHttpRequest是ajax的核心机制&#xff0c;它是IE5中首先引入的&#xff0c;是一种支持异步请求的技术。 简单的说&#xff0c;也…

面试官:请把ArrayList与LinkedList、Vector、Array做个比较

文章目录 ArrayList 和 LinkedList 有什么区别&#xff1f;Vector 和 ArrayList 有什么区别Array 和 ArrayList 一样吗&#xff1f;如何实现数组和 List 转换&#xff1f; ArrayList 和 LinkedList 有什么区别&#xff1f; ArrayList和LinkedList都是Java中常用的集合类 Array…

第四百九十八回

文章目录 1. 概念介绍2. 使用方法2.1 固定样式2.2 自定义样式 3. 示例代码4. 内容总结 我们在上一章回中介绍了"GetMaterialApp组件"相关的内容&#xff0c;本章回中将介绍使用get显示SnackBar.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在介…

查看iqn编码

cat /etc/iscsi/initiatorname.iscsi ## for each iSCSI initiator. Do NOT duplicate iSCSI InitiatorNames. InitiatorNameiqn.2004-10.com.ubuntu:01:9ebe1a68