【C++】学习笔记——string_2

news2024/12/24 3:17:42

文章目录

  • 六、string类
    • 2. 反向迭代器
      • const迭代器
    • string类对象的容量操作(补)
      • size()
    • 3. string类的元素访问
    • 4. string类的修改
  • 未完待续


结合文档食用~

六、string类

2. 反向迭代器

一般来说,迭代器都是正向的遍历容器,虽然可以通过从 end ** 遍历到 begin 的方法来反向遍历容器,但是有这样一种迭代器,叫做反向迭代器**,可以做到反向遍历容器。

#include<iostream>
#include<string>
using namespace std;

void test1()
{
	string s1("hello,world");
	// 反向迭代器 -- reverse_iterator
	string::reverse_iterator rit = s1.rbegin();
	while (rit != s1.rend())
	{
		cout << *rit << ' ';
		++rit;
	}
	cout << endl;
}

int main()
{
	test1();
	return 0;
}

在这里插入图片描述
在这里插入图片描述
反向迭代器就是反方向跑,每次+1其实都是往左跑。

const迭代器

当构造时使用 const 修饰,普通的迭代器就不能够使用了。

void test2()
{
	const string s1("hello,world");
	// 这里会出现报错
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << ' ';
		++it;
	}
	cout << endl;
}

此时由于类型不匹配,我们需要调整迭代器。
在这里插入图片描述

使用 const_iterator 就可以了。那么普通迭代器和 const迭代器 有什么区别呢?其实知道const就知道了,普通迭代器对容器是可读可写的,const迭代器就只可读

string类对象的容量操作(补)

在这里插入图片描述

size()

#include<iostream>
#include<string>
using namespace std;

void test3()
{
	string s1("hello,world");
	cout << s1 << endl;
	cout << s1.size() << endl;
	cout << s1.length() << endl;
	cout << s1.capacity() << endl;
	cout << s1.max_size() << endl;
}

int main()
{
	test3();
	return 0;
}

size() 函数返回string类中的元素个数。
length() 函数和 size() 函数作用一样,返回元素个数。
capacity() 函数返回容器的当前容量,即分配的空间,size() 是使用的空间。
max_size() 函数不常用,返回这个容器能够存储的最大长度,跟编译器有关,输出结果不唯一。
在这里插入图片描述
既然知道了 capacity ,我们来看一看VS环境下的C++扩容机制吧。

#include<iostream>
#include<string>
using namespace std;

void test4()
{
	string s;
	// 初始容量
	int sz = s.capacity();
	cout << sz << endl;
	// 循环插入数据
	for (int i = 0; i < 100; ++i)
	{
		s.push_back('a');
		// 容量有变化时
		if (sz != s.capacity())
		{
			sz = s.capacity();
			// 输出新的容量
			cout << "capacity changed:" << sz << endl;
		}
	}
}

int main()
{
	test4();
	return 0;
}

在这里插入图片描述
也不需要让大家找什么规律,我直接说了:①capacity 求的是不包含字符串末尾的 ‘\0’ 的空间,初始实际上是分配了 16 的空间大小,可用空间只有 15 个数据长度。②第一次扩容是 2倍扩容。③剩下的扩容都是 1.5倍扩容。在其他环境下不一定是这种扩容机制哦。

#include<iostream>
#include<string>
using namespace std;

void test5()
{
	string s("hello,world!!!!!!!!!!!!!!!!!!!!!!");

	cout << s << endl;
	cout << s.capacity() << endl;
	cout << s.empty() << endl;
	s.clear();
	cout << s << endl;
	cout << s.empty() << endl;
	cout << s.capacity() << endl;

}

int main()
{
	test5();
	return 0;
}

在这里插入图片描述

empty() 函数翻译过来就知道功能就是判断容器是否为空,为空返回true,非空返回false
clear() 函数就是清理的意思,它会将容易里的数据都清除。但是,我们发现,capacity() 并没有相应的减少,说明 clear 只清理了数据,并没有释放空间。那我们想要释放空间该怎么办?
在这里插入图片描述
string 提供了这样一个函数,作用是将 capacity 缩小到 size 大小。

#include<iostream>
#include<string>
using namespace std;

void test5()
{
	string s("hello,world!!!!!!!!!!!!!!!!!!!!!!");

	cout << s << endl;
	cout << s.capacity() << endl;
	cout << s.empty() << endl;
	s.clear();
	cout << s << endl;
	cout << s.empty() << endl;
	cout << s.capacity() << endl;
	// 缩容操作
	s.shrink_to_fit();
	cout << s.capacity() << endl;
}

int main()
{
	test5();
	return 0;
}

在这里插入图片描述
实际上它并不能把空间全部释放掉,最小缩容到 16 (有一个’\0’)。

#include<iostream>
#include<string>
using namespace std;

void test6()
{
	string s("hello,worlddddddddddddddddd");
	cout << s.size() << endl;
	cout << s.capacity() << endl;
	s.reserve(100);
	cout << s.capacity() << endl;
}

int main()
{
	test6();
	return 0;
}

在这里插入图片描述
reserve() 函数的作用就是手动分配空间,但是不一定刚刚好分派到你想要的大小。那么,reserve 可以缩容吗?上面情况是想要分配的空间比原来的 capacity 大,假如想要分配的空间比 size 大,比 capacity 小会怎样?比 size 小会怎样?

#include<iostream>
#include<string>
using namespace std;

void test6()
{
	string s1("hello,worlddddddddddddddddd");
	cout << s1.size() << endl;
	cout << s1.capacity() << endl;
	s1.reserve(100);
	cout << s1.capacity() << endl << endl;

	string s2("hello,worlddddddddddddddddd");
	s2.reserve(100);
	cout << s2.size() << endl;
	cout << s2.capacity() << endl;
	s2.reserve(50);
	cout << s2.capacity() << endl << endl;

	string s3("hello,worlddddddddddddddddd");
	s3.reserve(100);
	cout << s3.size() << endl;
	cout << s3.capacity() << endl;
	s3.reserve(10);
	cout << s3.capacity() << endl << endl;
}

int main()
{
	test6();
	return 0;
}

在这里插入图片描述
所以我们知道,reserve 只有比 capacity 大时才扩容。
reserve 是改变容量,resize() 就是改变数据个数。
在这里插入图片描述
由上图可知:①给 resize 的值比 size 小时,resize 会将多余的给删除,不会修改 capacity 的值。②当给 resize 的值比 size 大,比 capacity 小时,字符串后面会默认插入 ‘\0’,或者给定的值。③当给 resize 的值比 capacity 大时,字符串会扩容至 resize,然后赋值 ‘\0’ 或给定值。

3. string类的元素访问

在这里插入图片描述

#include<iostream>
#include<string>
using namespace std;

void test8()
{
	string s("hello,world");
	// [] 访问
	cout << s[6] << endl;
	// at 访问
	cout << s.at(6) << endl;
	// 直接取头部数据
	cout << s.front() << endl;
	// 直接取尾部数据
	cout << s.back() << endl;
}

int main()
{
	test8();
	return 0;
}

在这里插入图片描述

其中 []at 访问几乎没区别,只是对越界的检查方式不同。

4. string类的修改

在这里插入图片描述

#include<iostream>
#include<string>
using namespace std;

void test9()
{
	string s("123456789");
	cout << s << endl;
	// 字符串末尾追加
	s += '0';
	cout << s << endl;
	// 末尾追加
	s.append("987");
	cout << s << endl;
	// 尾插一个字符
	s.push_back('6');
	cout << s << endl;
	// 完全覆盖
	s.assign("13345889");
	cout << s << endl;
	// 从下标1开始插入
	s.insert(1, "23");
	cout << s << endl;
	// 从下标3开始删除两个字符
	s.erase(3, 2);
	cout << s << endl;
	// 从下标5开始,将1个字符给替换成
	s.replace(5, 1, "67");
	cout << s << endl;;
}

int main()
{
	test9();
	return 0;
}

在这里插入图片描述

insert / erase / replace 需要挪动数据,复杂度大,能不用就不用。这里函数太多,就不一一介绍了,多看看文档就会用了。


未完待续

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

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

相关文章

LuaJIT源码分析(三)字符串

LuaJIT源码分析&#xff08;三&#xff09;字符串 要表示一个字符串&#xff0c;核心就是需要知道字符串的长度&#xff0c;以及存放字符串具体数据的地址。lua的字符串是内化不可变的&#xff0c;也就是lua字符串变量存放的不是字符串的拷贝&#xff0c;而是字符串的引用。那么…

C语言⼆级指针如何操作字符串数组(指针数组)?

一、问题 对于字符串数组该如何操作&#xff08;⽽且是使⽤指针数组存储&#xff09;&#xff1f; 二、解答 使⽤指针的指针实现对字符串数组中字符串的输出。指向指针的指针即是指向指针数据的指针变量。这⾥创建⼀个指针数组 strings&#xff0c;它的每个数组元素相当于⼀个…

springcloud自定义全局异常

自行创建一个实体类 /*** 全局异常处理类**/ ControllerAdvice public class GlobalExceptionHandler {ExceptionHandler(Exception.class) ResponseBody public Result error(Exception e){e.printStackTrace(); return Result.fail();}/*** 自定义异常处理方法* param e * re…

神奇的Vue3 - 组件探索

神奇的Vue3 第一章 神奇的Vue3—基础篇 第二章 神奇的Vue3—Pinia 文章目录 神奇的Vue3了解组件一、注册组件1. 全局注册​2. 局部注册3. 组件命名 二、属性详解1. Props&#xff08;1&#xff09;基础使用方法&#xff08;2&#xff09;数据流向&#xff1a;单项绑定原则&…

深入图像分类:使用美国手语数据集训练定制化神经网络

引言 在前一篇博客中&#xff0c;我们探讨了如何使用MNIST数据集训练一个基础的神经网络来进行手写数字识别。在本文中&#xff0c;我们将更进一步&#xff0c;使用美国手语字母表&#xff08;ASL&#xff09;数据集来构建一个定制化的图像分类模型。通过这个过程&#xff0c;…

YOLOv9/YOLOv8算法改进【NO.128】 使用ICCV2023超轻量级且高效的动态上采样器( DySample)改进yolov8中的上采样

前 言 YOLO算法改进系列出到这&#xff0c;很多朋友问改进如何选择是最佳的&#xff0c;下面我就根据个人多年的写作发文章以及指导发文章的经验来看&#xff0c;按照优先顺序进行排序讲解YOLO算法改进方法的顺序选择。具体有需求的同学可以私信我沟通&#xff1a; 首推…

静态库、动态库回顾

回顾一下库相关的知识点&#xff0c;总结备忘一下。在某种情况下&#xff0c;你有了如下的代码&#xff0c;结构如下 //pra.h #include <stdio.h> void test_01(); //pra.c #include "pra.h" void test_01() {printf("xxxxxxx----->%s %s()\n",…

Docker 安装部署 postgres

Docker 安装部署 postgres 1、拉取 postgres 镜像文件 [rootiZbp19a67kznq0h0rgosuxZ ~]# docker pull postgres:latest latest: Pulling from library/postgres b0a0cf830b12: Pull complete dda3d8fbd5ed: Pull complete 283a477db7bb: Pull complete 91d2729fa4d5: Pul…

C#知识|汇总方法重载与静态方法应用技巧

哈喽&#xff0c;你好&#xff0c;我是雷工&#xff01; 今天学习C#方法重载与静态方法应用技巧的相关内容。 01 方法重载有什么好处&#xff1f; 1.1、可以有效的减少类的对外接口&#xff08;只显示一个方法比较简洁&#xff09;&#xff0c;从而降低类的复杂度。 1.2、方便…

ubuntu开启message文件

环境&#xff1a;ubuntu 20.04 1、首先需要修改 /etc/rsyslog.d/50-default.conf 文件&#xff1b;源文件中message被注释&#xff0c;如下图&#xff1a; 2、打开注释&#xff1a; 3、重启服务 systemctl restart rsyslog.service 如此即可&#xff01;

freeRTOS事件标志组(1-16)

def&#xff1a;事件标志组简介 事件标志位&#xff1a;用一个为来表示事件是否发生 事件标志组是事件标志位的集合可以简单的理解事件标志组&#xff0c;就是一个整数 事件标志组的特点: 1&#xff1a;它的每一个位表示一个事件&#xff08;高8位不算&#xff09; 2&#…

分布式与一致性协议之Raft算法与一致哈希算法(一)

Raft算法 Raft与一致性 有很多人把Raft算法当成一致性算法&#xff0c;其实它不是一致性算法而是共识算法&#xff0c;是一个Multi-Paxos算法&#xff0c;实现的是如何就一系列值达成共识。并且&#xff0c;Raft算法能容忍少数节点的故障。虽然Raft算法能实现强一致性&#x…

打印机-STM32版本 硬件部分

最终PCB EDA工程: 一、确定芯片型号 根据项目需求&#xff0c;梳理需要用到的功能&#xff0c; 电量检测&#xff1a;ADC 按键&#xff1a;IO input外部中断 LED&#xff1a;IO output 温度检测&#xff1a;ADC 电机控制&#xff1a;IO output 打印通讯&#xff1a;SPI …

HarmaonyOS鸿蒙应用科普课

一、什么是鸿蒙OS&#xff1f; 1.概念&#xff1a; 先给大家讲讲今天讲课的主题&#xff0c;鸿蒙OS是什么&#xff1f;鸿蒙系统大家都知道&#xff0c;就是一个操作系统&#xff0c;我们未来是为的成为鸿蒙程序员。所以我们不要将鸿蒙os完全等同于手机操作系统&#xff0c;太…

笔记:编写程序,绘制一个展示支付宝月账单报告的饼图,

文章目录 前言一、饼图是什么&#xff1f;二、分析题目三、编写代码总结 前言 编写程序&#xff0c;绘制一个展示支付宝月账单报告的饼图&#xff0c;实现过程如下&#xff1a; &#xff08;1&#xff09; 导入 matplotlib.pyplot 模块&#xff1b; &#xff08;2&#xff09;…

前端业务开发中使用原生js和elementui两种方式实现头像裁切上传的功能

日常业务开发中&#xff0c;无论是后台管理系统还是前台界面&#xff0c;都会遇到图片裁剪的业务需求&#xff0c;选择合适的尺寸或者图片的关键部分&#xff0c;满足我们的功能需求&#xff01;&#xff01; 效果预览 效果一&#xff1a; 效果二: 实现过程 1.原生js实现方…

全栈开发之路——前端篇(2)文件、组件与setup引入

全栈开发一条龙——前端篇 第一篇&#xff1a;框架确定、ide设置与项目创建 本文系该系列第二篇&#xff0c;主要将介绍各个文件的意义、组件结构与导入以及setup的引入。 目录 一、src外文件介绍.gitignore为git忽略文件env.d.ts用于识别其他文件index.htmljson文件vite.confi…

七、Google Protobuf

这里写自定义目录标题 一、编码和解码二、Netty本身的编码解码机制和存在的问三、Protobuf四、Protobuf示例1五、ProtoBuffer传输多种数据类型 一、编码和解码 二、Netty本身的编码解码机制和存在的问 netty提供的编码器 netty提供的解码器 存在的问题 无法跨语言序列化后…

【C语言】动态内存分配(一)

目录 1.为什么要有动态内存分配 2.malloc和free 2.1malloc 2.2free 1.为什么要有动态内存分配 我们已经掌握的内存开辟方式有: 但是上述的开辟空间的方式有两个特点: ⭐空间开辟大小是固定的。 ⭐数组在申明的时候&#xff0c;必须指定数组的长度&#xff0c;数组空间一旦…

大模型实体化:个人智能体为AI PC注入灵魂

从Alpha GO到Chat GPT&#xff0c;从DALL-E到Sora&#xff0c;AI时代的演进正行驶在快车道&#xff0c;人工智能正受到有史以来最高的关注。人们在生怕被快速变革的AI时代抛弃的同时&#xff0c;也不禁疑惑&#xff0c;AI浪潮的下一步在哪里&#xff1f; 大模型实体化&#xff…