Cherno C++学习笔记 P32 字符串

这篇文章我们来讲字符串。字符串可以说是最重要的变量类型了,因为对字符串的读写极大地影响到我们的程序和用户之间的交互。甚至很多很庞大的程序就只是在处理字符串。

对于字符串,我们同时需要有关于数组和指针的关系,字符串的实现与数组是紧密相连的。字符串本质是group of characters,是一堆字符的合集。而一堆字符可以组成各种各样我们所需的文本,这些其实都是字符串,所以字符串是C++处理文本的方式。主要目的是对文本进行操作并将其展现出来给用户互动。

那么在了解字符串之前,我们首先需要了解字符character。我们常见的所有的字母,符号,都是字符。在C++当中,我们用数据类型char来表示字符。而C++默认的字符编码方式是ASCII,一个字符用一个字节来表示,那么就总共有 2^8=256 种不同的选择。但是我们知道,如果只有256种选择,那么当我们想表示中文或者日文的时候,这个选择数量是远远不够的。所以为了能够表示更多的语言,我们有很多其他的编码方式来进行处理,比如utf_16,允许我们用两个字节,16位来表示一个字符,那么就可以有 2^16=65526 种不同的选择。这样可以表示的语言就更多了。当然在这里的话我们并不会深入编码的相关知识,只是给大家做个了解即可。

回到默认的char,因为char只有一个字节,所以可以用来按字节处理内存或者分配缓存等。在C++当中,我们通常会用单引号来表示一个字符。

文本和语言其实是非常非常复杂的东西,所以这里我们掌握基本的知识差不多就够用了。

那么有了字符之后,什么是字符串?字符串其实就是字符数组。我们可以举一个简单的例子。

#include<iostream>int main() {const char* name = "Cherno";std::cout << name << std::endl;std::cin.get();
}

这样我们就写下了一段有C风格的字符串定义代码。可以看到我们定义了一个const char类型的指针,指向了一个字符串。而在C++当中,字符串需要用双引号括起来。但是我们可以看到,这里我们是不需要写一个new的,也就是我们其实还是在栈上分配的内存。

接下来我们进入到内存里面去看看长什么样子:

可以在右侧看到我们数据的ASCII码,确实就是我们输入的Cherno。如果我们增加一句话,输出一下这个字符串的大小,看看是多少。

不过需要注意的是,如果我们使用上面的代码直接输出sizeof(name),那么它返回的其实是指针的大小,我们无法真的得到这个字符串的大小,所以我们这样写(VS2022下的结果):

#include<iostream>int main() {const char name[] = "Cherno";std::cout << name << std::endl;std::cout << sizeof(name) << std::endl;std::cin.get();
}

这样我们可以看到,输出的长度是7而不是我们看到的6,这是因为我们在最后还有一位空字符,这个被称为空终止符,是编译器自动加上来的。这个是因为name本身是指针的情况下,编译器依然应该知道在哪里停止下来,所以我们才能够直接输出。

需要注意的一点是,如果我们定义好了一个字符串,就意味着我们没有办法再改变它的长度了,如果想要更长的字符串,我们只能删除掉重新写一个。当然如果添加了const关键字,那就什么都改变不了了。

但是如果我们做这样的定义:

char name[6] = { 'C', 'h', 'e', 'r', 'n', 'o' };
std::cout << name << std::endl;

那么我们就会得到下面这个经典的输出:

也就是所谓的“口中直喊烫烫烫”,这个是因为什么,我们也可以进入内存里一探究竟。

因为未初始化的内存自动填充了cc,而0xcccc在GB2312当中刚好对应烫字,所以我们就会看到一堆烫烫烫了。这个成为stack guard,在debug模式下会出现的问题。

为了防止出现这么多烫烫烫,我们需要在最后面手动添加上空字符‘\0’或者直接是0

char name[7] = { 'C', 'h', 'e', 'r', 'n', 'o', '\0'};
char name[7] = { 'C', 'h', 'e', 'r', 'n', 'o', 0};

这两种定义方式是等效的,都是可以正常使用的。

以上都是C风格的字符串,那么在C++当中,我们更多使用的是string,而string相对而言容易使用得多。string类是一个char以及一些用来操纵这个char的方法的集合。实际上string还有一个模板类叫做basic_string,而我们使用的string是对basic_string的template specialization。

#include<iostream>
#include<string>int main() {std::string name = "Cherno";std::cout << name << std::endl;std::cout << name.size() << std::endl;std::cin.get();
}

这样我们就可以直接获得name的长度为6,而且如果我们把鼠标放到“Cherno”上面,会发现其真实的类型是const char[],这同样也是name的真实类型。这里的size则是C++风格的语句了,如果是C风格,还需要strlen()、strcpy()等函数。

如果我们有两个string类型的变量,我们可以直接对其进行相加操作,因为“+”在string类当中进行了重载,使得我们可以这样操作。

std::string name = "Cherno";
std::string language = "CPP";
std::string lesson = name + language;

但是需要注意的是,两个const char*是不能直接相加的,理由也很简单,两个指针类型怎么可能相加呢?但是因为“+”在string中被重载了,所以如果是一个string加一个const char*,这个是可以支持的。

std::string name = "Cherno";
std::string lesson = name + "CPP";

这样写是合法的。

那么如果就想直接把两个const char*相加,应该怎么办?答案是强制类型转换。

std::string lesson = (std::string)"Cherno" + "CPP";

这样就可以了。

string有很多方法,这里介绍另一个方法,叫做find,作用是寻找这个字符串内有没有对应的子串。但是因为string并没有contain方法来判断是否真的包含一个子串,所以需要我们自己写:

bool contains = lesson.find("no") != lesson.npos;

其中npos表示的是这个类型下最大的值,一般在如果find没有找到对应子串的时候返回。

最后讲一下有关于将string传递到函数中的问题。如果我们直接传递字符串,如下所示:

void PrintString(std::string string) {std::cout << string << std::endl;
}

那么会涉及一次字符串的拷贝,这个是会非常浪费时间的做法,因为拷贝字符串是很慢的,所以会导致性能的降低。

在我们不改变字符串的内容的情况下,可以只传入引用:

void PrintString(const std::string& string) {std::cout << string << std::endl;
}

添加const来表示我们也不会修改string的值。

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

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

相关文章

linuxCNC(五)HAL驱动的指令介绍

HAL驱动的构成 指令举例详解 从终端进入到HAL命令行&#xff0c;执行halrun&#xff0c;即可进入halcmd命令行 # halrun指令描述oadrt加载comoonent&#xff0c;loadrt threads name1 period1创建新线程loadusr halmeter加载万用表UI界面loadusr halscope加载示波器UI界面sho…

在做题中学习(78):数组中第K个最大元素

解法&#xff1a;快速选择算法 说明&#xff1a;堆排序也是经典解决topK问题的算法&#xff0c;但时间复杂度为&#xff1a;O(NlogN) 而将要介绍的快速选择算法的时间复杂度为: O(N) 先看我的前两篇文章&#xff0c;分别学习&#xff1a;数组分三块&#xff0c;随机选择基准…

分布式事务的前世今生-纯理论

一个可用的复杂的系统总是从可用的简单系统进化而来。反过来这句话也正确: 从零开始设计的复杂的系统从来都用不了&#xff0c;也没办法让它变的可用。 --John Gal 《系统学》 1975 1. 事务的概念 百科&#xff1a; 事务&#xff08;Transaction&#xff09;&#xff0c;一般是…

MySQL 服务无法启动

常见原因: 检查端口占用&#xff1a; 使用命令行工具&#xff08;如netstat&#xff09;来检查3306端口是否已被其他程序占用,输入netstat -ano&#xff08;Windows&#xff09;或netstat -tulnp | grep 3306&#xff08;Linux/Mac&#xff09;来查找3306端口的占用情况。如果…

基于Node.js的后端服务基础模块及应用

使用generator-express-no-stress-typescript脚手架工具创建一个图片上传服务的模板工程&#xff0c;执行如下指令&#xff1a; npm config set registry https://registry.npmmirror.com yo express-no-stress-typescript uploadService 可以看到后端框架如下&#xff1a; 先…

Hadoop生态圈框架部署 伪集群版(八)- Sqoop安装与配置

文章目录 前言一、Sqoop安装与配置&#xff08;手动安装配置&#xff09;1. 下载Sqoop2. 解压Sqoop安装包2.1 解压2.2 重命名 3. 配置Sqoop3.1 配置Sqoop环境变量3.2 修改 sqoop-env.sh 配置文件3.3 配置jar包3.3.1 配置MySQL驱动jar包3.3.2 配置commons-lang-2.6.jar包 4. 测试…

视频编辑技术:一键生成混剪视频的AI技术应用

随着视频内容的爆炸式增长&#xff0c;视频编辑技术也在不断进步。本文将探讨如何利用AI技术&#xff0c;实现一键生成混剪视频&#xff0c;并自动添加配音和字幕&#xff0c;以提高视频编辑的效率和质量。 AI技术在视频编辑中的应用 AI技术在视频编辑领域的应用越来越广泛&am…

笔记本外接显示屏没声音

1、笔记本正常有声音&#xff0c;但是外接显示屏后没有声音了怎么回事呢&#xff1f;原来外接显示屏后笔记本的声音输出会自动选择显示屏的音频输出&#xff0c;但是显示屏可能没有声音输出所以导致笔记本没有声音。 2、解决办法&#xff1a;打开笔记本设置&#xff0c;选择声…

Linux其二设置端口号,静态ip以及命令

目录 1、VI编辑器 【linux版本的文本文件】 2&#xff09; 补充的vi编辑器的其他内容(了解) 2、ln 连接的意思 link的缩写 3、文件的查看 【重点】 4、压缩与解压&#xff08;重点&#xff09; 5、find 查找命令 6、which & whereis 作用是一样的&#xff0c;表示某…

飞飞5.4游戏源码(客户端+服务端+工具完整源代码+5.3fix+5.4patch+数据库可编译进游戏)

飞飞5.4游戏源码&#xff08;客户端服务端工具完整源代码5.3fix5.4patch数据库可编译进游戏&#xff09; 下载地址&#xff1a; 通过网盘分享的文件&#xff1a;【源码】飞飞5.4游戏源码&#xff08;客户端服务端工具完整源代码5.3fix5.4patch数据库可编译进游戏&#xff09; 链…

【Linux】进程间通信 -- System V 消息队列

前言 上节Linux学习&#xff0c;我们学习了System V的共享内存&#xff0c;本节我们学习System V 的另一种通信方式 — 消息队列 文章目录 前言一. 消息队列的原理二.创建消息队列二. 查看消息队列三. 删除消息队列四. 读写数据结束语 一. 消息队列的原理 消息队列的本质同共享…

Elasticsearch入门之HTTP基础操作

RESTful REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。Web 应用程序最重要的 REST 原则是&#xff0c;客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在…

4.模块化技术之子程序

总学习目录请点击下面连接 SAP ABAP开发从0到入职&#xff0c;冷冬备战-CSDN博客 目录 ​编辑 1.模块化基础和概述 使用模块化有什么好处 两大类模块化技术 程序局部的模块化 SAP系统内全局模块化 封装有什么好处&#xff1f; 2.子程序模块化 三种传递类型 子程序结构…

69 mysql 中 is null 的实现

前言 Mysql 中我们偶尔会用到 字段为 NULL 的情况 这时候 我们只能使用查询 “select * from tz_test_02 where field1 is null;” 来进行 field1 字段为 null 的行的查询 然后如果是使用 “select * from tz_test_02 where field1 null;” 你会发现查询 不出数据 但是如…

51c嵌入式~单片机合集3

我自己的原文哦~ https://blog.51cto.com/whaosoft/12581900 一、STM32代码远程升级之IAP编程 IAP是什么 有时项目上需要远程升级单片机程序&#xff0c;此时需要接触到IAP编程。 IAP即为In Application Programming&#xff0c;解释为在应用中编程&#xff0c;用户自己的程…

网上图书购物管理系统|Java|SSM|VUE| 前后端分离

【一】可以提供远程部署安装&#xff0c;包扩环境 【二】提供软件相关的安装包 【三】如果需要提供java入门资料可咨询 【技术栈】 1⃣️&#xff1a;架构: B/S、MVC 2⃣️&#xff1a;系统环境&#xff1a;Windowsh/Mac 3⃣️&#xff1a;开发环境&#xff1a;IDEA、JDK1.8、M…

Python酷库之旅-第三方库Pandas(264)

目录 一、用法精讲 1251、pandas.tseries.offsets.WeekOfMonth.is_year_end方法 1251-1、语法 1251-2、参数 1251-3、功能 1251-4、返回值 1251-5、说明 1251-6、用法 1251-6-1、数据准备 1251-6-2、代码示例 1251-6-3、结果输出 1252、pandas.tseries.offsets.Las…

“为您的家电穿上防震铠甲:优质电器缓冲器

在地震频发地区或日常生活中&#xff0c;确保家电的安全和稳定至关重要。为了防止地震、意外碰撞或其他外力对家电造成损害&#xff0c;采用优质的电器缓冲器就像是为家电穿上了一层坚固的“防震铠甲”。这不仅能够有效减少因震动导致的损坏风险&#xff0c;还能显著延长家电的…

全连接层与链式求导法则在神经网络中的应用

目录 ​编辑 引言 全连接层的工作原理 前向传播 反向传播 链式求导法则及其在神经网络中的应用 链式求导法则 应用于全连接层 计算梯度 结论 引言 在深度学习领域&#xff0c;全连接层&#xff08;Fully Connected Layer&#xff0c;FC&#xff09;和链式求导法则是…

基于框架的逻辑回归:原理、实现与应用

目录 ​编辑 逻辑回归原理 损失函数与优化 正则化 基于框架的实现 1. 数据预处理 2. 模型初始化与训练 3. 模型评估与调优 4. 特征缩放 逻辑回归的应用 信用评分 医疗诊断 垃圾邮件识别 推荐系统 结论 在机器学习领域&#xff0c;逻辑回归是一种基础且强大的分类…