P23 C++字符串

news2024/11/27 14:52:22

目录

前言

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.coloradmin.cn/o/1259589.html

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

相关文章

基于OpenCV+YOLOv5实现车辆跟踪与计数(附源码)

导 读 本文主要介绍基于OpenCVYOLOv5实现车辆跟踪与计数的应用&#xff0c;并给出源码。 资源下载 基础代码和视频下载地址&#xff1a; https://github.com/freedomwebtech/win11vehiclecount main.py代码:​​​​​​​ import cv2import torchimport numpy as npfrom tr…

Vue CLI 初体验之如何创建一个项目并打开,以及组件的简单使用案例。

目录 什么是Vue CLI? 如何使用Vue CLI 创建一个项目 1.winr 打开cmd 输入vue create 1127(1127是文件名) 2.配置基础设置 选择Manually select features 选择Router和Vuex 选中vue版本&#xff08;我这里选vue3&#xff09; 剩下的看自己需要&#xff0c;如果不确定就一…

3、Segment Anything

github 创建anaconda环境 conda create -n ASM python3.8下载依赖包 # pytorch>1.7 and torchvision>0.8 conda install pytorch1.11.0 torchvision0.12.0 torchaudio0.11.0 cudatoolkit11.3 -c pytorchpip install githttps://github.com/facebookresearch/segment-a…

13、LCD1602调试工具

LCD1602调试工具 使用LCD1602液晶屏作为调试窗口&#xff0c;提供类似Printf函数的功能&#xff0c;可实时观察单片机内部数据的变化情况&#xff0c;便于调试和演示。 main.c #include <REGX52.H> #include "LCD1602.h" #include "Delay.h"//存储…

快速搭建一个SpringCloud、SpringBoot项目 || 项目搭建要点

1. 基本结构 建立springcloud项目从表入手&#xff0c;分析好需求建立表结构后&#xff0c;使用mybatis-plux生成POJO类&#xff0c;在对应的model模块中。 2. 微服务部分架构 2.1 依赖 service 微服务模块的依赖仅包含如下&#xff0c;数据库等依赖包含在model中&#xff0c…

【解决视觉引导多个位置需要标定多个位置的问题】

** 以下只针对2D定位&#xff0c;就是只有X、Y、Rz三个自由度的情况。** 假设一种情况&#xff0c;当视觉给机器人做引导任务时&#xff0c;零件有多个&#xff0c;分布在料框里&#xff0c;视觉需要走多个位置去拍&#xff0c;那么只需要对第一个位置确定拍照位&#xff0c;确…

力扣6:N字形变化

代码&#xff1a; class Solution { public:string convert(string s, int numRows){int lens.size();if(numRows1){return s;}int d2*numRows-2;int count0;string ret;//第一行&#xff01;for(int i0;i<len;id){rets[i];}//第k行&#xff01;for(int i1;i<numRows-1;…

智能优化算法应用:基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于教与学算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.教与学算法4.实验参数设定5.算法结果6.参考文献7.…

超越GPT-4,拥有联网能力,Kimi-Chat大模型已免费使用,国内直接访问

目前ChatGPT的所有免费用户都已可以使用带有语音功能的ChatGPT。 人吧&#xff0c;总是贪婪的&#xff0c;我还想要ChatGPT Plus用户独享的“联网”功能。 目前对于ChatGPT来说&#xff0c;不想交钱&#xff0c;别拥有“联网”能力了&#xff0c;于是我找到了一个后起之秀&…

【差旅游记】新疆哈密回王府印象

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 2023年11月4号&#xff0c;那天的风的确挺大&#xff0c;逛完哈密博物馆考虑要不要去旁边的哈密回王府逛逛。想着来都来了&#xff0c;虽然网上评价不太好&#xff0c;还是去溜达一圈吧&#xff0c;于是决定自己去转转…

为啥网络安全那么缺人,但很多人却找不到工作?

文章目录 一、学校的偏向于学术二、学的东西太基础三、不上班行不行 为什么网络安全的人才缺口那么大&#xff0c;但是大学毕业能找到网安工作的人却很少&#xff0c;就连招聘都没有其他岗位多&#xff1f; 明明央视都说了网络安全的人才缺口还有300多万&#xff0c;现在找不到…

C++ 用ifstream读文件

输入流的继承关系: C++ 使用标准库类来处理面向流的输入和输出: iostream 处理控制台 IOfstream 处理命名文件 IOstringstream 完成内存 string 的 IO每个IO 对象都维护一组条件状态 flags (eofbit, failbit and badbit),用来指出此对象上是否可以进行 IO 操作。如果遇到错误…

vue实战——登录【详解】(含自适配全屏背景,记住账号--支持多账号,显隐密码切换,登录状态保持)

效果预览 技术要点——自适配全屏背景 https://blog.csdn.net/weixin_41192489/article/details/119992992 技术要点——密码输入框 自定义图标切换显示隐藏 https://blog.csdn.net/weixin_41192489/article/details/133940676 技术要点——记住账号&#xff08;支持多账号&…

「江鸟中原」有关HarmonyOS-ArkTS的Http通信请求

一、Http简介 HTTP&#xff08;Hypertext Transfer Protocol&#xff09;是一种用于在Web应用程序之间进行通信的协议&#xff0c;通过运输层的TCP协议建立连接、传输数据。Http通信数据以报文的形式进行传输。Http的一次事务包括一个请求和一个响应。 Http通信是基于客户端-服…

进程等待讲解

今日为大家分享有关进程等待的知识&#xff01;希望读完本文&#xff0c;大家能有一定的收获&#xff01; 正文开始&#xff01; 进程等待的引进 既然我们今天要讲进程等待这个概念&#xff01;那么只有我们把下面这三个方面搞明白&#xff0c;才能真正的了解进程等待&#x…

形象建设、生意经营、用户运营,汽车品牌如何在小红书一举多得?

随着小红书在多领域的持续成长&#xff0c;现在来小红书看汽车的用户&#xff0c;需求逐渐多元化与专业化。近1年的时间&#xff0c;有超过1亿人在小红书「主动搜索」过汽车内容&#xff0c;大家已经不仅限于玩车、用车&#xff0c;更是扩展到了百科全书式的看、选、买、学各个…

Python3 selenium 设置元素等待的三种方法

为什么要设置元素等待&#xff1f; 当你的网络慢的时候&#xff0c;打开网页慢&#xff0c;网页都没完全打开&#xff0c;代码已经在执行了&#xff0c;但是没找到你定位的元素&#xff0c;此时python会报错。 当你的浏览器或电脑反应慢&#xff0c;网页没完全打开&#xff0c;…

12、模块化编程

模块化编程 1、传统方式编程&#xff1a;所有的函数均放在main.c里&#xff0c;若使用的模块比较多&#xff0c;则一个文件内会有很多的代码&#xff0c;不利于代码的组织和管理&#xff0c;而且很影响便朝着的思路 2、模块化编程&#xff1a;把各个模块的代码放在不同的.c文件…

java--单继承、Object

java是单继承的&#xff0c;java中的类不支持多继承&#xff0c;但是支持多层继承。 反证法&#xff1a; 如果一个类同时继承两个类&#xff0c;然后两个类中都有同样的一个方法&#xff0c;哪当我创建这个类里的方法&#xff0c;是调用哪父类的方法 所以java中的类不支持多继…