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.rhkb.cn/news/486159.html

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

相关文章

Visual Studio 2022 项目配置常用选项

作为一名C++开发者,经常需要配置第三方库,今天来跟大家截图一下,方便大家快速配置: 头文件包含目录: 或者: 库文件包含目录:

leetcode每日一题(20241207)(20241204补)

leetcode每日一题&#xff08;20241206&#xff09;和补一下 &#xff08;20241204&#xff09;的这天的 &#xff08;20241204): 2056. 棋盘上有效移动组合的数目:题目描述&#xff1a; 有一个 8 x 8 的棋盘&#xff0c;它包含 n 个棋子&#xff08;棋子包括车&#xff0c;后…

AJAX和XHR、fetch、axios的关系

AJAX中有两套原生的API&#xff0c;一个是XHR(XMLHttpRequest)&#xff0c;一个是Fetch API axios是第三方库&#xff0c;在浏览器环境中使用的是XHR umi-request也是第三方库&#xff0c;在浏览器环境中使用的是Fetch 在 AJAX&#xff08;Asynchronous JavaScript and XML&am…

Sarcomere仿人灵巧手ARTUS,20个自由度拓宽机器人作业边界

Sarcomere Dynamics 是一家深度技术先驱&#xff0c;通过开发和商业化仿人机械来改变机器人行业。专注于为科研人员&#xff0c;系统集成商和制造商提供更实惠、更轻便且更灵活的末端执行器替代品。凭借创新的致动器技术&#xff0c;创造了一款紧凑、轻便且非常坚固的机械手Art…

【Python库安装】Python环境安装hdf4处理库pyhdf

目录 pyhdf库简介功能简介 pyhdf库安装1. 使用 pip 安装&#xff08;推荐方法&#xff09;2. 从源码安装3. conda安装 参考 pyhdf库简介 pyhdf 是一个 Python 库&#xff0c;用于读取和处理 HDF4 格式的文件&#xff08;注意&#xff1a;HDF5 格式文件需要用 h5py 库&#xff…

34.1 uber开源的m3db简介

本节重点介绍 : m3db自己的定位m3db自己的架构m3db自己的组件 两句话简介 M3最初是在优步开发的&#xff0c;目的是提供对优步业务运营&#xff0c;微服务和基础架构的可视性由于M3具有轻松进行水平扩展的能力&#xff0c;因此它为所有监视用例提供了一个集中式存储解决方案…

WebSocket 通信说明与基于 ESP-IDF 的 WebSocket 使用

一、 WebSocket 出现的背景 最开始 客户端&#xff08;Client&#xff09; 和 服务器&#xff08;Server&#xff09; 通信使用的是 HTTP 协议&#xff0c;HTTP 协议有一个的缺陷为&#xff1a;通信只能由客户端&#xff08;Client&#xff09;发起。 在一些场景下&#xff0…

OpenSSL 自建CA 以及颁发证书(网站部署https双向认证)

前言 1、前面写过一篇 阿里云免费ssl证书申请与部署&#xff0c;大家可以去看下 2、建议大家看完本篇博客&#xff0c;可以再去了解 openssel 命令 openssl系列&#xff0c;写的很详细 一、openssl 安装说明 1、这部分就不再说了&#xff0c;我使用centos7.9&#xff0c;是自…

使用javaScript生成随机迷宫

效果预览 我制作了一个 CodePen&#xff0c;以动画形式展示随机迷宫的创建过程&#xff0c;以便更加直观的观察算法的工作原理。&#xff08;点击即可访问生成新迷宫&#xff09; 基本思路 使用javaScript生成随机迷宫的核心思想是使用一个“深度优先搜索”&#xff08;DFS&a…

【ArkTS】列表组件的“下拉刷新”和“上拉加载”

系列文章目录 【ArkTS】关于ForEach的第三个参数键值 【ArkTS】“一篇带你读懂ForEach和LazyForEach” 【小白拓展】 【ArkTS】“一篇带你掌握TaskPool与Worker两种多线程并发方案” 【ArkTS】 一篇带你掌握“语音转文字技术” --内附详细代码 【ArkTS】技能提高–“用户授权”…

Java项目实战II基于微信小程序的消防隐患在线举报系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着城市化进程的加快&…

每日十题八股-2024年12月7日

1.说说hashmap的负载因子 2.Hashmap和Hashtable有什么不一样的&#xff1f;Hashmap一般怎么用&#xff1f; 3.ConcurrentHashMap怎么实现的&#xff1f; 4.分段锁怎么加锁的&#xff1f; 5.分段锁是可重入的吗&#xff1f; 6.已经用了synchronized&#xff0c;为什么还要用CAS呢…

CTF学习24.11.19[音频隐写]

MISC07[音频隐写] 隐写术 隐写术是一门关于信息隐藏的技巧与科学&#xff0c;所谓信息隐藏指的是不让除预期的接收者之外的任何人知晓信息的传递事件或者信息的内容。隐写术的英文叫做Steganography&#xff0c;来源于特里特米乌斯的一本讲述密码学与隐写术的著作Steganograp…

掌握谈判技巧,达成双赢协议

在当今竞争激烈且合作频繁的社会环境中&#xff0c;谈判成为了我们解决分歧、谋求共同发展的重要手段。无论是商业合作、职场交流&#xff0c;还是国际事务协商&#xff0c;掌握谈判技巧以达成双赢协议都具有极其关键的意义。它不仅能够让各方在利益分配上找到平衡点&#xff0…

HTTPS的工作过程

1.HTTPS协议原理 1.1HTTPS协议的由来 HTTP在传输网络数据的时候是明文传输的&#xff0c;信息容易被窃听甚至篡改&#xff0c;因此他是一个不安全的协议&#xff08;但效率高&#xff09;。在如今的网络环境中&#xff0c;数据安全是很重要的&#xff08;比如支付密码又或者各…

鸿蒙UI开发——渐变色效果

1、概 述 ArkTs可以通过颜色渐变接口&#xff0c;设置组件的背景颜色渐变效果&#xff0c;实现在两个或多个指定的颜色之间进行平稳的过渡。 目前提供三种渐变类型&#xff1a;线性渐变、角度渐变、径向渐变。 我们在鸿蒙UI布局实战 —— 个人中心页面开发中&#xff0c;默认…

距离与AoA辅助的三维测距算法(适用于四个基站的情况的单点定位),MATLAB代码

本MATLAB 代码实现了一个基于LOS/NLOS混合环境的单点定位系统&#xff0c;主要用于估计目标物体的单点位 文章目录 代码运行结果源代码代码功能概述主要步骤分析初始化部分 绘图与输出 代码运行结果 定位结果如下&#xff1a; 命令行的坐标和误差输出&#xff1a; 部分代码…

Vue指令(一)--v-html、v-show、v-if、v-else、v-else-if、v-on、v-bind、v-for、v-model

目录 &#xff08;一&#xff09;初识指令和内容渲染指令v-html 1.v-html 案例&#xff1a; 官网的API文档 &#xff08;二&#xff09;条件渲染指令v-show和v-if 1. v-show 2. v-if &#xff08;三&#xff09;条件渲染指令v-else和v-else-if 案例 &#xff08;四…

记一次由docker容器使得服务器cpu占满密码和密钥无法访问bug

Bug场景&#xff1a; 前几天在服务器上部署了一个免费影视网站&#xff0c;这个应用需要四个容器&#xff0c;同时之前的建站软件workpress也是使用docker部署的&#xff0c;也使用了三个容器。在使用workpress之前&#xff0c;我将影视软件的容器全部停止。 再使用workpress…

【JavaEE 进阶(一)】SpringBoot(上)

博主主页: 33的博客 文章专栏分类:JavaEE ??我的代码仓库: 33的代码仓库?? ???关注我带你了解更多进阶知识 目录 1.前言2.Spring3.第一个SpringBoot程序4.Spring MVC 4.1建立连接 4.1.1RequestMapping使用 4.2请求 4.2.1传递单个参数4.2.2传递多个参数4.2.3传递一个对象…