P23 C++字符串

目录

前言

01 什么是字符串

02 字符串是怎么工作的呢?

2.1 字符

2.2 字符串

2.3 如何知道指向hello world的这个指针多大

03 使用字符串

04 字符串传参


前言

本期我们将讨论 C++ 中的字符串。

首先,什么是字符串?

01 什么是字符串

字符串是一个接一个字符的一组字符。

字符可以是字母、数字、符号,这类东西基本上就是文本,这些对我们来说很常见,作为人类,我们想要在电脑上以某种方式来表示文本。当然文本可以是一个单个的字符,也可以是一整个段落,可以是一个单词,也可以是一堆单词,所有这些被称为字符串的东西都是一个文本字符串。

所以我们会有这样的问题,当我们编程的时候,需要一些方法能够在我们的程序中将文本表现出来,这就要用到 C++ 字符串。对于我们来说,这是一种能够表示和处理文本的方法。

02 字符串是怎么工作的呢?

为了理解 C++ 中的字符串是如何工作的,你首先需要理解字符到底是什么以及字符是如何运作的。

2.1 字符

字符通常以字母符号、数字等以不同形式呈现

你可能已经注意到在 C++ 中有一种数据类型叫做 char,它是 character 的缩写,它代表一个字母的内存,它再一些情况下很有用,

  1. 因为它能把指针转换为 char 型指针,你可以用字节来做指针运算。
  2. char 对于分配内存缓冲区也很有用,因为如果你想分配1k的内存,你可以分配1024个 char。
  3. 它对字符串和文本也很有用,因为 C++ 对待字符的默认方式是通过 ASCII 字符进行文本编码的

我们用一个字节来表示一个字符,也就是8个比特,这意味着我们有2的8次方种可能的结果,也就是256种可能性,有些语言的字符数量远远超过了这个数量,所以我们不能所有语言都只用一个字节表示一个字符,8个比特根本不够。然而16个比特,也就是16位字符编码,我们就有2的16次方种不同的可能性,也就是65536种字符可以表示,这个基本是足够的。

还有很多其它的编码,但是在 C++ 中我们一般使用原始数据类型,在这里,我们暂时认定 char 是一个字节。

2.2 字符串

接下来我们讨论一下字符串是如何在 C++ 中运作的。

字符,就是 char 类型数据,而字符串实际上就是字符数组,而数组又是一组元素的集合,所以,一组字符组成了字符串或文本。

你可能已经注意到,在本系列中,我们经常将字符串称为 const char* ,让我们来看看它是如何工作的。

#include <iostream>

int main()
{
    const char *buffer = "hello world" ;
    return 0;
}

我们可以通过 const char* 声明一个字符串,让它等于双引号下的某种文字。

这其实是 C 语言风格定义字符串的方式,C++ 有一个库可以使得字符串操作更为简单,但即使是这样,了解这种方式是如何工作的仍然很重要。

你其实不是必须把它声明为 const,但是人们通常这样做的原因是不想去改变这些的值。因为字符串是不可变的,这意味着你不能扩展字符串使它变大。这是一个固定分配的内存块,如果你想要一个最大的字符串,它需要执行一次重新分配分配并删除旧的字符串。

  1. 这里的 char* 并不意味着它是在堆上分配的,你不能通过调用 delete 来删除它,——记住一点,如果你们没有使用 new,就不要使用 delete。
  2. 现在这个字符串我们无法修改其中的某个值。比如 buffer[2] = 's',这会导致错误。所以如果你知道你不会修改字符串,就可以加上 const。

一个字符串在内存中是什么样的呢?

我们设置一个断点来调试一下。

你可以看到 hello world这个词就是由12个字符组成。还可以看到紧接着有一个被设置为0的字节,它被称为空终止字符,那是字符串结束的地方。

2.3 如何知道指向hello world的这个指针多大

或许你已经注意到了,我们似乎从来不知道 buffer有多大,因为它只是一个指针,那么如何知道它的大小呢?

空终止符可以帮助我们。

字符串是从指针的内存地址开始,一直往后继续,直到它碰到0。当我们决定将其打印到控制台的时候,你可以看到它正常被输出,但它只是一个指针,那么它是如何知道终点的呢?——直到/0,因为这就是它的空终止符。

如果你想自己声明字符串,我们也可以使用下面这种方式。

#include <iostream>

int main()
{
    const char *buffer = "hello world" ;
    char buf[] = {'h','e','l','l','o'};
    return 0;
}

我们可以使用 char 类型的数组来完成。

它有5个字符,我们对它进行了初始化,把它设置为单个字符,C++ 的字符是通过单引号定义的。

上面的 buf是一个数组,不是一个字符串。这只是一个包含5个字符的数组,没有设置空终止符,

我们对程序做上面的修改,这样buf才是一个字符串。

‘\0’ 就是 null,它的 ASCII 码值是0,这里也可以直接写0。

我们应该如何在 C++ 中用字符串呢?

03 使用字符串

在 C++ 中的标准库有一个名为 String 的类,实际上还有一个类叫 BaseString,它是一个模板类,String 是 baseString 类的模板版本,模板参数是 char,这叫做模板特化 template specialization 。意思就是将 BaseString 模板类中的模板参数设为 char,char 是每一个字符背后的实际类型(还有一种叫做 wstring 的东西,也就是宽字符串)。

在 C++ 中使用的字符串是 std::string 。

那它是怎么工作的呢?

基本上它是由一个 char 数组以及一些用来操作数组的函数构成的。

首先第一件事就是 #include,其实在 name里面已经有 string 的定义了,你可以看到我们的上面的代码中没有包含头文件 string 也可以正常运行。

string 有一个构造函数,它接受 char 或者 const char 参数,你把鼠标悬浮在字符串上面,你可以看到 ganlan 实际上是一个 const char 数组。

尽管 iostream 对 string 已经有一个定义了,因为一些特殊的原因,我还是建议你包含一下。std::string 是一个有很多功能的类。比如 size(),我们可以得到它的尺寸,如果我们是 const char 或者 char我们就需要用到 C 中的函数,比如 strlen(),还有 strcpy() 可以用来复制字符串。上面所有的这些功能,在 string 中都可以找到,这就是我们现在使用字符串的方式。另一件常见的操作是追加字符串。

我想在 test 后加上 hello,如果按照下面的写法会出现错误。

原因很简单,你实际上是想将两个 const char 的数组相加。这个双引号里面的东西是 const char 数组,它不是真正的字符串,我们总不能把两个指针相加吧。

所以如果你想完成这个操作,一个简单的方法就是把它分开成多行,然后再做相加的操作。

name 是一个字符串,你把它加到一个字符串上,+= 这个操作符在 string 类被重载了,这样写是没有问题的。 

04 字符串传参

我写了一个 test函数,我要传递一个字符串,那么你不应该像上面那样写。

不这样做的原因是:

这实际上是一个副本。

当你这样给函数传递给一个函数时,你实际上时复制这个类对象。如果想要做 string += "h" 这样的事情,它不会影响到传递的原始字符串,所以,这显然是一个只读函数,我们不能在里面修改任何东西。

这意味着程序会动态地在堆上分配一个全新的 char 数组来存储已经得到的完全相同的文本,这个过程相当慢。在某些情况下,这是一个主要的短板。因为字符串操作是很频繁的,因此当你传递一个这样的字符串而且是在只读的情况下,需要确保通过常量引用传递它。

可以在在参数类型前面加上 const 和引用 &,这样,就告诉我们,这是一个引用,意味着它不会被复制,意味着我们承诺不会在这里修改它。

以上就是字符串的主要内容了。

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

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

相关文章

Batch Norm简明图解【批归一化】

Batch Norm&#xff08;批归一化&#xff09; 是现代深度学习实践者工具包的重要组成部分。 在批归一化论文中引入它后不久&#xff0c;它就被认为在创建可以更快训练的更深层次神经网络方面具有变革性。 Batch Norm 是一种神经网络层&#xff0c;现在在许多架构中普遍使用。 …

Electronica慕尼黑电子展 Samtec团队与21ic分享虎家产品与方案

【摘要/前言】 “希望但凡是能够使用到连接器的场合都有Samtec的身影” 在慕尼黑上海电子展现场&#xff0c;Samtec华东区销售经理章桢彦先生在与21ic副主编刘岩轩老师的采访中&#xff0c;如是说道。这是一种愿景&#xff0c;更是Samtec的努力方向。短短一句话&#xff0c;…

WebSocket协议在java中的使用

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

aspera传输方案怎么样,需要选择aspera替代方案吗

Aspera传输方案是一种高速、可靠的文件传输解决方案&#xff0c;适用于需要大规模传输大文件或数据集的企业和组织。Aspera采用UDP协议及自己开发的FASP协议进行加速传输&#xff0c;能够在高延迟、高丢包网络环境下实现稳定快速的传输。 Aspera传输方案具有以下优点&#xff1…

ArcGIS10.x系列 Python工具箱教程

ArcGIS10.x系列 Python工具箱教程 目录 1.前提 2.需要了解的资料 3.Python工具箱制作教程 4. Python工具箱具体样例代码&#xff08;DEM流域分析-河网等级矢量化&#xff09; 1.前提 如果你想自己写Python工具箱&#xff0c;那么假定你已经会ArcPy&#xff0c;如果只是自己…

ESP32-Web-Server编程- JS 基础5

ESP32-Web-Server编程- JS 基础5 概述 JS 编程内容颇多&#xff0c;我们提供一些简单的示例&#xff0c;先玩再学&#xff0c;边玩边学。 示例1-演示通过 JS 进行温度转换 资源链接 对应示例的 code 链接 &#xff08;点击直达代码仓库&#xff09; 示例2-增加网页弹窗 演…

Maven回顾

Maven 下载&#xff08;前提要有jdk&#xff09; Maven 下载地址&#xff1a;Maven – Download Apache Maven 设置 Maven 环境变量 添加环境变量 MAVEN_HOME&#xff1a; 右键 "计算机"&#xff0c;选择 "属性"&#xff0c;之后点击 "高级系统设置…

【libGDX】加载G3DJ模型

1 前言 libGDX 提供了自己的 3D 格式模型文件&#xff0c;称为 G3D&#xff0c;包含 g3dj&#xff08;Json 格式&#xff09;和 g3db&#xff08;Binary 格式&#xff09;文件&#xff0c;官方介绍见 → importing-blender-models-in-libgdx。 对于 fbx 文件&#xff0c;libGDX…

day65

今日回顾内容 web应用 HTTP协议 web应用 一、什么是web应用程序 Web应用程序是一种可以通过Web访问的应用程序&#xff0c;程序的最大好处是用户很容易访问应用程序&#xff0c;用户只需要有浏览器即可&#xff0c;不需要再安装其他软件 对于传统的应用软件来说&#xff0c;…

zi定义指令

hello&#xff0c;我是小索奇&#xff0c;精心制作的Vue系列持续发放&#xff0c;涵盖大量的经验和示例&#xff0c;如果对您有用&#xff0c;可以点赞收藏哈~ 自定义指令 自定义指令就是自己定义的指令&#xff0c;是对 DOM 元素进行底层操作封装 ,程序化地控制 DOM&#xff…

前端实现埋点

前端实现埋点 如何去了解用户呢&#xff1f;最直接有效的方式就是了解用户的行为&#xff0c;了解用户在网站中做了什么&#xff0c;呆了多久。而如何去实现这一操作&#xff0c;这就涉及到我们前端的埋点了。 埋点方式 什么是埋点&#xff1f; 所谓埋点是数据采集领域&…

leetcode:414. 第三大的数

一、题目 函数原型&#xff1a;int thirdMax(int* nums, int numsSize) 二、思路 将数组降序排序。 如果数组元素个数小于3&#xff0c;直接返回第一个元素&#xff1b; 如果数组元素个数大于等于3&#xff0c;且不同元素个数小于3&#xff0c;直接返回第一个元素&#xff1b; …

AIGC系列之:Variational Auto Encoder-VAE模块

目录 1.VAE 概述 2.概率分布 3.损失函数 4.重参数技巧 5.维度对 VAE 的影响 6.损失函数对VAE的影响 7.总结 VAE原始https://arxiv.org/abs/1312.6114 论文解读&#xff1a;https://mp.weixin.qq.com/MzI1MjQ2O 1.VAE 概述 变分自动编码器&#xff08;Variational auto…

STM32CubeIDE(CUBE-MX hal库)----串口通信

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、CUBE-MX可视化配置二、发送数据和接收数据1.HAL库串口的阻塞模式和非阻塞模式2.HAL库串口阻塞模式数据发送函数3.HAL库串口阻塞模式数据接收函数4.HAL库串口…

Pygame直线绘制

文章目录 lines光线反射 pygame.draw中有4个绘制直线的函数&#xff0c;列表如下 一条线段多条线段正常linelines抗锯齿aalineaalines 一条和多条线段的输入参数如下 line(surface, color, start_pos, end_pos, width1)lines(surface, color, closed, points, width1) line…

搭建Appium工具环境

1、安装Java Development Kit&#xff08;JDK&#xff09; 前往Oracle官网下载JDK。 在https://www.oracle.com/java/technologies/javase-jdk11-downloads.html 找到最新版本的JDK。根据操作系统选择适合的版本&#xff0c;并根据指示下载安装程序。 安装JDK。运行下载的安…

如何将mobi、awz3、epub格式转化为pdf

偶然之间有个需求就是网上下载了一些书籍的格式没法打开看&#xff0c;或者是想把kindle的书籍转换成pdf 那么经过一番折腾找到了两个可以用的工具站分享给大家&#xff0c;有需要的可是尝试下&#xff0c;小编这边测试了可以用&#xff0c;就是下载的时候慢的一匹。。。 第一…

计算机网络——数据链路层-数据链路层概述(介绍、三个重要问题、使用广播信道的数据链路层、其他问题)

目录 介绍 三个重要问题 封装成帧 差错检测 可靠传输 使用广播信道的数据链路层 其他问题 介绍 本篇对数据链路层进行概述&#xff0c;我们首先来看看数据链路层在网络体系结构中的地位&#xff1a; 主机H1给主机H2发送数据&#xff0c;中间要经过三个路由器和电话网、…

Xshell连接VMware虚拟机中的CentOS

Xshell连接VMware虚拟机中的CentOShttps://www.cnblogs.com/niuben/p/13157291.html 步骤&#xff1a; 1. 检查Linux虚拟机的网络连接模式&#xff0c;确保它是NAT模式。&#xff08;由于只在本机进行连接&#xff0c;所以没有选择桥接模式。当然&#xff0c;桥接模式的配置会…

Ubuntu 22.03 LTS 安装deepin-terminal 实现 终端 分屏

deepin-terminal 安装 源里面自带了这个软件&#xff0c;可以直接装 sudo apt install deepin-terminal 启动 按下Win键&#xff0c;输入deep即可快速检索出图标&#xff0c;点击启动 效果 分屏 CtrlShiftH 水平分割 CtrlShiftJ 垂直分割 最多分割成四个小窗口&#xff0…