C++入门 string(1)

目录

string类简介

 string类的常用接口说明 

string类对象的常见构造

string类对象的访问及遍历操作 

 operator[ ] 

begin + end

 rbegin + rend


 string类简介

  1. string是表示字符串的字符串类
  2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
  3. string在底层实际是:basic_string模板类的别名,typedef basic_string string;
  4. 不能操作多字节或者变长字符的序列
  5. 在使用string类时,必须包含#include<string>以及using namespace std;

 string类的常用接口说明 

string类对象的常见构造

C++98定义了多个构造函数,但是我们最常用的只有一下三种: 

(constructor)函数名称功能说明
string() (重点)构造空的string类对象,即空字符串
string(const char* s) (重点)用C-string来构造string类对象
string(size_t n, char c)string类对象中包含n个字符c
string(const string&s) (重点)拷贝构造函数

具体实现方法如下图所示:

#include<iostream>
#include<string>

using namespace std;

void test_string1()
{
	// 常用
	string s1;						// 构造空的string类对象s1
	string s2("hello world");		// 用C格式字符串构造string类对象s2
	string s3(s2);					// 拷贝构造s3

	cin >> s1;
	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
}

 其次,string类依然遵守隐式类型转换原则在引用对象时,需要加上const修饰

void push_back(const string& s)
{
	//.......
}

void test_string2()
{
	string s1 = "hello world";
	// 隐式类型转换
	//这里s2引用的是临时变量,临时变量具有常性,需要用const修饰
	const string& s2 = "hello world";

	 构造
	//string s3("hello world");
	//push_back(s1);
	//以后尾插不用先构造再尾插,直接尾插就可以

	push_back("hello world");
}

s1这样写也是可以的,C++98为我们写了赋值运算符重载,可以直接使用。


string类对象的访问及遍历操作 

函数名称功能说明
operator[ ](重 点)返回pos位置的字符,const string类对象调用
begin + endbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rendbegin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
范围forC++11支持更简洁的范围for的新遍历方式

 operator[ ] 

string类中operator[ ] 成员函数类似下面代码,引用返回减少一次拷贝构造,也能通过别名修改返回的对象,assert保证了如果传进去的 i 超过了size直接断言报错。

class string
{
public:
	// 引用返回
	// 1、减少拷贝
	// 2、修改返回对象
	char& operator[](size_t i)
	{
		assert(i < _size);
		return _str[i];
	}
private:
	char* _str;
	size_t _size;
	size_t _capacity;
};

注意:string的类成员对象,如果要统计string变量的大小,要计算类成员变量的内存大小,按照内存对齐原则(32位系统对齐系数是4)即一个string变量大小是12(如图所示的类成员变量总计)而不是算字符串中字符个数,字符的个数与string变量本身内存大小无关

void test_string3()
{
	string s1("hello world");
	s1[0] = 'x';	//'h'修改为'x'

	cout << s1.size() << endl;
	//cout << s1.length() << endl;
	//输出11  不包含\0
	//lenth和size等价,但是为了后续其他数据计算方便,统一写size

	for (size_t i = 0; i < s1.size(); i++)
	{
		s1[i]++;	//字符串中每个元素+1(ASCII)
	}
	// 越界检查  s1[20];	//assert(i < _size);

	for (size_t i = 0; i < s1.size(); i++)
	{
		//cout << s1.operator[](i) << " ";   显示调用
		cout << s1[i] << " ";    //遍历字符串打印每个字符
	}
	cout << endl;

	const string s2("hello world");
	// 不能修改
	//s2[0] = 'x';
}

如果string被const修饰,还可以将第一个元素修改为'x'吗?如果不能,为什么呢?看下图:

 s1,s2优先匹配相似度高的函数,即遵循模板参数的匹配原则


begin + end

begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器,begin和end可以实现字符串的遍历

void test_string4()
{
	string s1("hello world");

	// 遍历方式1:下标+[]
	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;

	//遍历方式2: 迭代器
	//auto it1 = s1.begin();   //这样写前提是你知道他是什么类型
	string::iterator it1 = s1.begin();
	while (it1 != s1.end())
	{
		*it1 += 3;	
		cout << *it1 << " ";
		++it1;	//控制it1移动
	}
	cout << endl;

	//遍历方式3: 范围for
	// 底层角度,他就是迭代器
	for (auto& e : s1)
	{
		e++;	//想要修改加上引用
		cout << e << " ";
	}
	cout << endl;
}

这样就有三种方式可以遍历数组, 我们可以将迭代器想象成指针,如下图所示:

 从begin()开始,到end()就停止遍历,可以修改字符串里的值。

void test_string5()
{
	const string s1("hello world");
	//string::const_iterator it1 = s1.begin();
	auto it1 = s1.begin();
	while (it1 != s1.end())
	{
		// 不能修改
		//*it1 += 3;

		cout << *it1 << " ";
		++it1;
	}
}

 那么加上const修饰应该怎么实现权限的平移呢?另外const_iterator为什么中间要加短下划线?如下图所示:

注意:在编写程序时,const_iterator中间要写下划线 


 rbegin + rend

rbegin记录字符串尾元素,rend记录字符串头元素,两者为反向迭代器,共同使用可以实现数组的逆序访问。

void test_string6()
{
	const string s1("hello world");
	//string::const_reverse_iterator cit1 = s1.rbegin();
	auto cit1 = s1.rbegin();
	while (cit1 != s1.rend())
	{
		// 不能修改
		//*cit1 += 3;

		cout << *cit1 << " ";
		++cit1;
	}
	cout << endl;

	string s2("hello world");

	string::reverse_iterator it2 = s2.rbegin();
	//auto it2 = s2.rbegin();
	while (it2 != s2.rend())
	{
		*it2 += 3;

		cout << *it2 << " ";
		++it2;
	}
	cout << endl;
}

 在图中所示:此处依旧遵循模板参数的匹配原则

此处rbegin从右向左遍历至rend,++往左移动, 编译器实现逻辑如下图所示: 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024年工业设计与制造工程国际会议(ICIDME 2024)

2024年工业设计与制造工程国际会议 2024 International Conference on Industrial Design and Manufacturing Engineering 会议简介 2024年工业设计与制造工程国际会议是一个集结全球工业设计与制造工程领域精英的盛会。本次会议旨在为业界专家、学者、工程技术人员提供一个分享…

偏微分方程算法之抛物型方程差分格式编程示例三(C-N格式)

目录 一、研究问题 二、C++代码 三、结果分析 一、研究问题 已知其精确解为。分别取以下三种步长: ①

人大京仓数据库关闭大小写敏感

人大京仓数据库关闭大小写敏感 1、先删除data&#xff08;Kingbase\ES\V8\&#xff09;文件夹下的所有文件夹 2、接着找到initdb.exe所在位置&#xff0c;我的位置是在这里D:\Kingbase\ES\V8\Server\bin&#xff0c;然后输入cmd,运行一下 initdb -E UTF-8 -D C:\Kingbase\ES…

中国新兴的数字证书品牌——JoySSL

JoySSL是一个基于全球可信顶级根创新推出的新一代https数字证书&#xff0c;也是中国为数不多的自主品牌SSL证书。以下是关于JoySSL的详细介绍&#xff1a; 1 品牌背景&#xff1a; JoySSL是网盾安全旗下的产品&#xff0c;专注于网络安全技术服务、安全防护系统集成、数据安…

Craig Federighi 和 John Giannandrea 在 WWDC 上谈论苹果智能技术

WWDC 主题演讲结束后&#xff0c;苹果公司的克雷格-费德里吉&#xff08;Craig Federighi&#xff09;和约翰-吉安南德雷亚&#xff08;John Giannandrea&#xff09;坐下来&#xff0c;更深入地讨论了苹果智能公司在人工智能方面所做的努力&#xff0c;包括该公司是如何训练模…

【Vue】获取模块内的actions方法

目标&#xff1a; 掌握模块中 action 的调用语法 (同理 - 直接类比 mutation 即可) 注意&#xff1a; 默认模块中的 mutation 和 actions 会被挂载到全局&#xff0c;需要开启命名空间&#xff0c;才会挂载到子模块。 调用语法&#xff1a; 直接通过 store 调用 $store.di…

机器学习笔记:focal loss

1 介绍 Focal Loss 是一种在类别不平衡的情况下改善模型性能的损失函数最初在 2017 年的论文《Focal Loss for Dense Object Detection》中提出这种损失函数主要用于解决在有挑战性的对象检测任务中&#xff0c;易分类的负样本占据主导地位的问题&#xff0c;从而导致模型难以…

C#项目实战

事件 public delegate void NumManipulationHandler(NumEventArgs e); // 基于上面的委托定义事件 public event NumManipulationHandler ChangeNum;public class Program{public static void Main(){NumEvent even new NumEvent(0);even.ChangeNum EventAction.Action;even…

【全篇】C语言从入门到入土

【全篇】C语言从入门到入土 文章目录 【全篇】C语言从入门到入土第一章 前言如何去学习&#xff0c;学习方法论 第二章 初识1.代码编译工具2.c程序的基础框架3.数据的表现形式变量1.要先定义后使用&#xff08;变量名的定义是由自己决定的&#xff0c;一般倾向于顾文生义&#…

Python基础教程(九):Lambda 函数

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

道路堵塞监测识别摄像机

道路堵塞监测识别摄像机是现代城市交通管理的重要利器&#xff0c;其功能多样、效果显著&#xff0c;对缓解交通拥堵、提高通行效率有着重要作用。 该摄像机采用高清摄像头&#xff0c;能够实时捕捉道路上的交通情况。无论是车辆密度还是行驶速度&#xff0c;都能清晰记录&…

从零手写实现 nginx-17-nginx.conf 全局的默认配置

前言 大家好&#xff0c;我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的&#xff0c;可以参考我的另一个项目&#xff1a; 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …

Android Studio历史版本

android studio的历史版本

BCZYYb(钡铈锆钇镱)主要用作电解质 我国技术研究与生产步伐正在加快

BCZYYb&#xff08;钡铈锆钇镱&#xff09;主要用作电解质 我国技术研究与生产步伐正在加快 BCZYYb&#xff0c;钡铈锆钇镱氧化物&#xff0c;钙钛矿结构&#xff0c;外观为白色至浅黄色粉末状&#xff0c;主要用作电解质&#xff0c;功能是传输离子&#xff0c;具有化学稳定性…

Python 基础语法详解(五)

Python 基础语法详解&#xff08;五&#xff09; Python 循环语句14.1 while 循环实操&#xff1a;①重要命令&#xff1a;continue 和 break②while 循环使用 else 语句实操&#xff1a;③pass 语句 14.2 for 循环实操&#xff1a;①上实操——通过索引序列迭代元素②for 循环…

OCP-042之:Oracle实例管理

2. Oracle实例管理 2.1 Instance管理 Oracle实例(instance)是一组Oracle后台进程和内存结构的集合。 后台进程主要包括SMON,PMON,DBWR,CKPT和LGWR等;内存结构包括数据库高速缓冲区、重做日志缓冲区、共享池、大池等组成系统全局区(SGA)的重要组件。实例主要实现对数据库的…

我开发了一款只用一个注解就实现统计访问量的工具框架

大家有可能在实际开发项目中会遇到这样的情况。实现计数器功能&#xff0c;比如统计网站访问量、用户点击次数等。大家有可能把它放在redis里面&#xff0c;也有可能把它放在MYSQL里面。但是这样大家都需要动手实现很多的代码。繁琐而复杂。于是我就想在 simple-cache框架中发布…

C#之EntityFramework的应用

目录 1&#xff0c;名词概述。 2&#xff0c;实体数据模型EDM介绍。 3&#xff0c;规范函数。 4&#xff0c;查看Linq转换成的SQL语句。 5&#xff0c;数据的增删改查。 5.1&#xff0c;数据查询 5.2&#xff0c;数据插入 5.3&#xff0c;数据更新 5.4&#xff0c;数据…

深入探索 Rust 的 clap 库:命令行解析的艺术

版本声明 Rust: 1.76clap: 4.5.1clap_complete 4.5.1rpassword: 7.3.1 结论先行 本文将从 CLI&#xff08;Command Line Interface&#xff09;命令行工具的概述讲起&#xff0c;介绍一个优秀的命令行工具应该具备的功能和特性。然后介绍 Rust 中一个非常优秀的命令行解析工…

8.1 基本打印功能

本文仅供学习交流&#xff0c;严禁用于商业用途&#xff0c;如本文涉及侵权请及时联系本人将于及时删除 在使用“MFC应用”项目模板生成应用程序的过程中&#xff0c;如果在“高级功能”窗口中不取消对打印和打印预览的设置&#xff0c;那么应用程序就已经具备了简单的打印和打…