C++中String的语法及常用接口用法

在C语言中,string是一个标准库类(class),用于处理字符串,它提供了一种更高级、更便捷的字符串操作方式,string 类提供了一系列成员函数和重载运算符,以便于对字符串进行操作和处理。

一、string类

在学习 string 前,我们不妨先来了解一下 string 类到底是什么,有什么用呢?我们先来了解一下基本的概念吧

C++标准库都是英语解释。我们也应该试着去适应,不懂的可以查阅。当然,在这里我就直接给出翻译,主要是以下内容:

字符串是表示字符序列的类;

  • 标准的字符串类提供了对此类对象的支持,其接口类似于标准字符容器的接口,但添加了专门用于操作单字节字符字符串的设计特性。

  • string类是使用char(即作为它的字符类型,使用它的默认char_traits和分配器类型(关于模板的更多信息,请参阅basic_string)。

  • string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类,并用char_traits和allocator作为basic_string的默认参数(根于更多的模板信息请参考basic_string)。

  • 注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作。

二、string的常用见用法

2.1 string对象的构造

2.1.1 string对象的构造的使用方法

最为常用的无非就是我们用串string来构造一个对象,也就是存储一个字符,常用的方法有如下几点:

  • string()——构造空的 string 类对象,即空字符串;

  • string(const char* s)——用 char* 来构造 string 类对象;

  • string(size_t n, char c)——string类对象中包含n个字符c

  • string(const string&s)——拷贝构造函数

下面是使用方法所对应的实例,帮助更好的理解其用法。

三、string常用结构的底层实现

3.1 初建结构

我们通过上述的构造,不难发现也不难理解string的底层其实就是一个字符指针,该指针指向一个数组。当然,我们还需要两个变量来维护其有效长度(_size)数组容量(_capacity)

其次,我们自己实现的string类为了区分std命名空间,我们可自己设置一个命名空间。处型的模拟实现如下:

namespace gtm
{class string{public://string()//	:_str(new char[1])//	, _size(0)//	,_capacity(0)//{//}//string(const char* str)//	:_str(new char[strlen(str) + 1])  //三次strlen函数,效率低。//	,_size(strlen(str))//	,_capacity(strlen(str))//{//	strcpy(_str, str);//}// 不再使用strlen函数,初始化列表与变量声明顺序固定string(const char* str = "") //默认空串。注意:空串是以 \0 结尾{_size = strlen(str);_capacity = _size;_str = new char[_size + 1];strcpy(_str, str);}~string(){delete[] _str;_str = nullptr;_size = _capacity = 0;}private:char* _str;size_t _size;size_t _capacity;};

3.2 返回大小和容量

这两个部分,是比较容易实现的两部分。同时也是较为常用的两部分。具体如下:

size_t size() const{return _size;}size_t capacity() const{return _capacity;}

3.3 拷贝构造和赋值重载

这两部分较为复杂的两部分。其中均需要深拷贝去实现完成,而浅拷贝是不可以的。注意:拷贝构造使用一个已定义变量去初始化另一个变量,赋值重载是两个已定义变量进行赋值

具体实现如下:

//深拷贝//string(const string& s)//	:_str(new char[s._capacity+1])//	,_size(s._size)//	,_capacity(s._capacity)//{//	strcpy(_str, s._str);//}void swap(string& tmp){//调用全局的swap::swap(_str, tmp._str);::swap(_size, tmp._size);::swap(_capacity, tmp._capacity);}//借助变量tmpstring(const string& s):_str(nullptr) , _size(0), _capacity(0){string tmp(s._str);swap(tmp);}//赋值//string& operator=(const string& s)//{//	if(this == &s)//	{//		return *this;//	}//	//先开空间拷贝数据,以防new失败销毁原来的空间//	char* tmp = new char[s._capacity + 1];//	strcpy(tmp, s._str);//	delete[] _str;//	_str = tmp;//	_size = s._size;//	_capacity = s._capacity;//	return *this;//	//delete[] _str;//	//_str = new char[s._capacity + 1];//	//strcpy(_str, s._str);//	//_size = s._size;//	//_capacity = s._capacity;//	return *this;//}//string& operator=(const string& s)//{//	if(this == &s)//	{//		return *this;//	}//	string tmp(s._str);//	swap(tmp);//  return *this;//}string& operator=(string s){if (this == &s){return *this;}swap(s);return *this;}

上述的辅助重载我们巧妙地借助了临时变量s。当赋值完成后,出了作用域s会自动调用戏后进行销毁,这里是需要反复理解的。

3.4 扩容(reserve)

我们可简单的理解reserve为扩容(扩容的前提为要求的容量比原来的大),但是我们要记得把字符数组中原有的内容拷贝过来,并且释放之前所动态开辟的空间。 具体实现如下:

void reserve(size_t capacity){if (capacity > _capacity){char* tmp = new char[capacity + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = capacity;}}

3.5 插入(push_back、append、operator+=、insert)

插入的实现,主要的点就是是否要进行扩容。其次,当我们实现push_back和append后,其他的均可复用这两个结构进行实现。具体实现如下:

        void push_back(char ch){if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}_str[_size] = ch;_size++;_str[_size] = '\0';}void append(const char* str){size_t len = strlen(str);if (len + _size > _capacity){reserve(len + _size >= _capacity * 2 ? len + _size : _capacity * 2);}strcpy(_str + _size, str);_size += len;}void append(const string& s){append(s._str);}void append(int n, char ch){reserve(_size + n);for (int i = 0; i < n; i++){push_back(ch);}}string& operator+= (char ch){push_back(ch);return *this;}string& operator+= (const char* str){append(str);return *this;}string& insert(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity){reserve(_capacity == 0 ? 4 : _capacity * 2);}//注意,当运算数一个是有符号,另一个是无符号时,有符号的运算数会强制类型转换为无符号数。pos等于0的位置插入,end--后为超大数据,会出错。//int end = _size;//while (end >= (int)pos)//{//	_str[end + 1] = _str[end];//	end--;//}size_t end = _size+1;while (end > pos){_str[end] = _str[end - 1];end--;}_str[pos] = ch;_size++;return *this;}string& insert(size_t pos, const char* str){assert(pos <= _size);size_t len = strlen(str);if (len + _size > _capacity){reserve(len + _size >= _capacity * 2 ? len + _size : _capacity * 2);}size_t end = _size + len;while (end >= pos+len){_str[end] = _str[end - len];end--;}for (int i = pos,j=0; j < len;j++, i++){_str[i] = str[j];}_size += len;return *this;}

string 在C++中算是比较重要的了,也是入门时必须所学的容器。在平常中使用的频率较高,所以我们不仅要掌握其简单的用法,更应该去了解其底层的实现。这有助于我们后续的使用和理解。本篇文章列举出了string中常用的语法和接口底层的底层实现,这些都是我们应该熟练掌握的内容。

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

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

相关文章

scala TraversableOnce

scala TraversableOnce 1. 由来 TraversableOnce是Scala中的一个特质&#xff08;trait&#xff09;&#xff0c;它定义了一组操作&#xff0c;用于遍历和处理集合类型的元素。它是Scala集合层次结构中的基本概念之一。 2. 示例 以下是使用TraversableOnce的简单示例&#…

Redis高可用:主从复制详解

目录 1.什么是主从复制&#xff1f; 2.优势 3.主从复制的原理 4.全量复制和增量复制 4.1 全量复制 4.2 增量复制 5.相关问题总结 5.1 当主服务器不进行持久化时复制的安全性 5.2 为什么主从全量复制使用RDB而不使用AOF&#xff1f; 5.3 为什么还有无磁盘复制模式&#xff…

C# 一种求平方根的方法 立方根也可以 极大 极小都可以

不知道研究这些干啥&#xff0c;纯纯的浪费时间。。。 public static double TQSquare(double number){Random random1 new Random(DateTime.Now.Millisecond);double x1 0, resultX1 0, diff 9999999999, diffTemporary 0;for (int i 0; i < 654321; i){if (random1…

怎么做Tik Tok海外娱乐公会呢?新加坡市场怎么样?

一、为什么选择TikTok直播 1. 海外市场潜力巨大 • 自2016年始&#xff0c;多家直播平台陆续拓展至东南亚、中东、俄罗斯、日韩、欧美、拉美等地区。 • 海外市场作为直播发展新蓝海&#xff0c;2021年直播行业整申请cmxyci体规模达百亿美元&#xff0c;并维持高速增长。 &a…

C++初阶语法——内部类

前言&#xff1a;内部类&#xff0c;顾名思义是定义在类中的类&#xff0c;许多人会以为它属于外部的类&#xff0c;实际上并不是&#xff0c;它们是两个独立的类&#xff0c;但是内部类受外部类类域的限制。 目录 一.概念二.特性1.内部类和外部类相互独立2.内部类是外部类的友…

10,遍历任意参

遍历可变参数 遍历可变参数获取可变参数大小通过递归方式遍历可变参数通过可变参数特性来求和 遍历可变参数 #pragma oncetemplate<class ... ParamTypes> void Func(paramTypes &... param) {}可以看作是有一个结构体里面装满了参数&#xff0c;把结构体放到…中。…

Git多版本并行开发实践

本文目的&#xff1a; 实现多个项目同时进行的git多版本管理工作流。 名词解释&#xff1a; feature-XXXX&#xff1a;特性分支指CCS中一个项目或者一个迭代&#xff0c;在该分支上开发&#xff0c;完成后&#xff0c;合并&#xff0c;最后&#xff0c;删除该分支&#xff0c;…

【广州虚拟现实开发】VR智能中控系统进一步提高VR教学管理水平

随着科技的不断发展&#xff0c;虚拟现实(VR)技术已经逐渐走进了人们的生活。在教育领域&#xff0c;VR技术也得到了广泛的应用&#xff0c;尤其是在教学终端中控系统方面。那么&#xff0c;广州华锐互动开发的VR智能中控系统对学校有何益处呢&#xff1f; 首先&#xff0c;VR智…

RocketMQ(模式详解,安装)及控制台安装

下载 环境 64位操作系统&#xff0c;推荐 Linux/Unix/macOS 64位 JDK 1.8下载地址 https://rocketmq.apache.org/zh/download/ RocketMQ 的安装包分为两种&#xff0c;二进制包和源码包。 二进制包是已经编译完成后可以直接运行的&#xff0c;源码包是需要编译后运行的。 单…

LVS负载均衡DR(直接路由)模式

在LVS&#xff08;Linux Virtual Server&#xff09;负载均衡中的DR&#xff08;Direct Routing&#xff09;模式下&#xff0c;数据包的流向如下&#xff1a; 客户端发送请求到负载均衡器&#xff08;LVS&#xff09;的虚拟IP&#xff08;VIP&#xff09;。负载均衡器&#x…

基于C++ 的OpenCV绘制多边形,多边形多条边用不用的颜色绘制

使用基于C的OpenCV库来绘制多边形&#xff0c;并且为多边形的不同边使用不同的颜色&#xff0c;可以按照以下步骤进行操作&#xff1a; 首先&#xff0c;确保你已经安装了OpenCV库并配置好了你的开发环境。 导入必要的头文件&#xff1a; #include <opencv2/opencv.hpp&g…

Bryntum Scheduler Pro 5.5.1 Crack

BRYNTUM 调度程序专业版,专业的日程安排小部件 Bryntum Scheduler Pro 5.5.1 一个专业有大脑的调度UI组件。Scheduler Pro 可帮助您安排任务&#xff0c;同时考虑资源和任务的可用性。 连接您的任务 让 Scheduler Pro 处理剩下的事情。它将根据您定义的链接安排您的任务并遵守任…

BNC连接器市场分析:全球BNC连接器市场规模不断增长

产品定义及统计范围 BNC&#xff08;Bayonet-Neill-Concelman&#xff09;连接器是一种通常用于视频和音频信号传输的电连接器。它是以其两位发明者Paul Neill和Carl Concelman的名字命名的&#xff0c;他们在20世纪40年代末开发了这种连接器。BNC连接器是一种设计用于同轴电缆…

ansible 修改远程主机nginx配置文件

安装ansible brew install ansible 或者 pip3 install ansible 添加远程主机 设置秘钥 mac登录远程主机 ssh -p 5700 root192.168.123.211 ssh localhost #设置双机信任 ssh-kyegen -t rsa #设置主机两边的ssh配置文件 vi /etc/ssh/sshd_config/ PermitRootL…

UniApp 制作高德地图插件

1、下载Uni插件项目 在Uni官网下载Uni插件项目&#xff0c;并参考官网插件项目创建插件项目. 开发者须知 | uni小程序SDK 如果下载下来项目运行不了可以参考下面链接进行处理 UniApp原生插件制作_wangdaoyin2010的博客-CSDN博客 2、引入高德SDK 2.1 在高德官网下载对应SD…

207. 课程表

思路 首先要完全理解题意&#xff0c;这道题的[a,b]并不是b满足了a就可以真正的学习a这门课了&#xff0c;因为a还有可能需要其他选修课的条件。类似下图。   这题的思路在于使用合适的数据结构来存储&#xff0c;这里用hash表来存储如果1这门课可以修了之后&#xff0c;可以…

docker pull 设置代理 centos

On CentOS the configuration file for Docker is at: /etc/sysconfig/docker 用 root 权限打开 text editor sudo gedit 注意 加引号 Adding the below line helped me to get the Docker daemon working behind a proxy server: HTTP_PROXY“http://<proxy_host>:&…

linux下shell编写软件看门狗

遇到一个问题&#xff0c;就是软件崩溃&#xff0c;可以让软件自动重启&#xff0c;而且数据库必须是软件崩溃之前的 #!/bin/sh while true do /app/app/record -qws cp -pr /msata/db/db_record.db /data/log/db_record.db mv /msata/db/db_record1.db /msata/db/db_record.d…

ubuntu20.04磁盘满了 /dev/mapper/ubuntu--vg-ubuntu--lv 占用 100%

问题 执行 mysql 大文件导入任务&#xff0c;最后快完成了&#xff0c;查看结果发现错了&#xff01;悲催&#xff01;都执行了 两天了 The table ‘XXXXXX’ is full &#xff1f; 磁盘满了&#xff1f; 刚好之前另一个 centos 服务器上也出现过磁盘满了&#xff0c;因此&a…

神经网络基础-神经网络补充概念-30-搭建神经网络块

概念 搭建神经网络块是一种常见的做法&#xff0c;它可以帮助你更好地组织和复用网络结构。神经网络块可以是一些相对独立的模块&#xff0c;例如卷积块、全连接块等&#xff0c;用于构建更复杂的网络架构。 代码实现 import numpy as np import tensorflow as tf from tens…