【C++ Primer Plus】4

2 字符串

字符串是存储在内存的连续字节中的一系列字符;C++处理字符串的方式有两种,

  1. c-风格字符串(C-Style string)
  2. string 类

2.1 c-风格字符串(C-Style string)

2.1.1 char数组存储字符串(c-风格字符串)

将字符串存储在char数组中,每个字符都位于自己的数组元素中

以空字符(null character)结尾,空字符被写作\0,ASCII 为0,用于标记字符串的结尾。

不应将字符串的字符数组当做字符串来处理,末尾相差一个’\0’
在这里插入图片描述

缺点:
(1)造容易出现因’\0’造成的输出错误
(2)大量引号带来的输入压力;

2.1.2 字符串常量(string constant)

字符数组初始化为字符串,自动加上结尾的空字符:char boss[8]="Bozo" //隐式地包括结尾的空字符;
在这里插入图片描述

字符串常量(使用双引号)不能与字符常量(单引号)互换
char shirt_size = ‘S’; //fine 字符
char shirt_size = “S” // illegal
char shirt_size[ ]= “S” // fine 字符串

2.1.3 数组中 定义与初始化 字符串常量

  1. 定义与初始化
// 定义的同时初始化
char  bird[]="Mr. Hellen"
cout << bird;

//先定义再初始化
char name1[20]; 
​cin >> name1;  
// input:lihua
​cout << "hello"<< name1 << ", good morning!"

  1. 将键盘或文件输入读入到数组中(cin; getline; get)

cin :以空格、制表符和换行符确定字符串结束位置,这意味着(1)cin在获取字符数组输入时只能读取一个单词;读取后,cin将该字符串放到数组中,并自动在结尾添加空字符;(2) 无法防止输入溢出

getline(): 读取整行,在读取指定数目的字符 或 通过回车键输入的换行符来输入结尾;
cin.getline( arrayName , charNamber);
两个参数:第一个参数用来存储输入行的数组的名称。第二个参数要读取字符数;
e.g. cin.getline(name,20); 将姓名读取到一个包含20个元素的name数组中,这行包含的字符不超过19个。
在这里插入图片描述

  • get():istream类中的一个函数
//用法1:类似于getline,但get不再读取或丢弃换行符,而是留在输入队列中;
const int Arsize = 20;
cin.get(name, ArSize);
cin.get(dessert,Arsize); //problem;读取到第一个字符是换行符,以为到行尾,无法跨过换行符继续输入;

//解决方案
//不带任何参数的cin.get(),可读取下一个字符;
cin.get(name, ArSize);
cin.get();  //read newline
cin.get(dessert,Arsize);
//合并写法:
cin.get(name, ArSize).get()

tips:使用建议使用get(),而不是getline,get()使输入更仔细,并且,老式实现没有getline;
get可以知道读取的原因是已经读取了整行,而不是由于数组已经填满;如果出现这种情况,查看下一个字符,如果是换行,那么说明读取了整行,否则,说明还有其他输入;

  • 空行问题
cin >>year;  // 输入 2024 回车;
cin.getline(address,80// Wallstreet
//无法获得地址,因为getline读取到换行符后会以为是空行,并将空字符串赋给address
// 解决方案
cin >> year;
cin.get(); // or cin.get(ch);

(cin >> year).get(); //or (cin >> year).get(ch) 

2.1.4 输出(访问)字符串

输出

使用cout 来显示string 对象。
cout << name1[ ];

访问存储在 string 对象中的字符

//获取字符数组元素值
cout << name1[0];

2.1.5 复制、拼接、附加字符串:

  • 复制
strcpy(charr1,charr2);
  • 拼接:注意目标存储过小,拼接溢出问题;
//拼接时不会在被连接的字符串之间添加空格
cout << "hel" << "lo, world!";
// cstring头文件
strcat(charr1,charr2);
strcat(charr1,"hello"); 

//strncat;strncopy;

2.1.6 sizeof 计算数组长度

// sizeof(name);  
// strlen( )返回存储在数组中的字符串的长度,而不是数组本身的长度;

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int main()
{
	char name1[20]="lihua";  
	cout << name1 << endl;
	cout << "the length of name1 is (sizeof) "<< sizeof(name1) << endl;
	cout << "the length of name1 is (strlen) "<< strlen(name1) << endl;
   return 0;
}
lihua
the length of name1 is (sizeof) 20
the length of name1 is (strlen) 5

2.2 string 类

包含在头文件string中;string类位于命名空间std中;

2.2.1 初始化


string str1;  //声明创建一个长度为0的string对象 
cin >> str1; 

string str2 =  "happy"

2.2.2 输出 cout

2.2.3 复制/赋值、拼接和附加

复制/赋值: str1 = str2; 一个string对象合一赋给另一个对象
拼接:str3=str1 +str2 ;
附加:str3 += “pro max”;
长度:int len1 = str1.size();
// str1不是作为参数,而是位于函数名前;str1是一个对象,size是一个类方法,方法是一个函数,只能通过其所属类的对象进行调用。

2.2.4 string的I/O

cin >> str; // read a word into the str string object;

getlline(cin,str) // 这里的getlinge不是类方法,而是将cin作为参数,指出到哪里查找输入;

R"( 和) " 作为定界符
cout << R"(Jim “King” Tutt uses “\n” instead endl.) "
//可在结果中显示’’ ‘’ () ;而不用 ‘’
输出:Jim “King” Tutt uses “\n” instead endl.

3 结构体

6 指针

指针是一个变量,其存储的是(所指向元素的)地址,而不是值本身。
&——获取变量的地址;
* ——运算符被称为间接值或解除引用运算符,

*pointer 可得到该指针存储地址的值
指针manly ; manly表示一个地址,*many表示存储地址对应元素的值。
指针的定义:typeName *pointer;
初始化 int home=100; int *pointer = &home;

  1. 声明指针

TypeName * pointerName

double *pd;
char *pc;
  1. 初始化指针
double *pd;
double *pa
char *pc;

double pi =3.14;
pd = &pi;

pc=new char;
pa =new double[30];

int *fellow;
*fellow =23333; //dangerous!野指针!
fellow = 0x1234567//mismatch!等号两边一边是地址,一遍是数值;
fellow = (int *) 0x1234567;// match !等号两边均为地址,但是不提倡;
  1. 对指针解除引用:获得指针指向的值

cout << *pd; // 输出pd存储的地址所指向的元素的值;输出结果为3.14;
*pc = 's'; // 修改pc存储的地址所指向的元素的值为s;

  • *使用new&delete 管理内存

note:决不要对未被初始化为适当地址的指针解除引用,形成野指针;
所以一定要在对指针应用解除引用运算符*之前,将指针初始化为一个确定的、适当的值;
可以采用赋值法或者通过new来分配内存
使用new分配内存&使用delete释放内存

typeName * pointer_name = new typeName;
int* pt = new int; //new运算符根据类型来确定需要多少字节的内存,接下来将地址赋给pt;

int happy; int *pn =&happy;

// 两种方法都是将一个int变量符地址赋给了指针。第二种通过名称happy来访问int,
第一种情况下只能通过该指针进行访问。我们可以说pt指向一个数据对象,指的是为数据项分配的内存块,好处是它使得程序在管理内存方面有了更大的控制权。

int* pt = new int;
*pt =1001;
cout << " int value = " << *pt << " location = " << pt << endl;  //通过打印*pt打印值
sizeof(pt) //
sizeof(*pt) //返回值为4,int的4个字节的int值

地址只指出了指针所指向对象地址的开始,而没有指出其类型或长度信息,但是由于new声明了指针类型,因此程序知道*pt是4个字节(double的话是8个字节,指针pt所占用的字节是固定的)。

new从堆(heap)或自由存储区(free store)的内存区域分配内存。变量nights和pd的值都存储在栈(stack)的内存区域中。

释放内存
delete pt;

  1. 区分指针和指针所指向的值

double pi =3.14;
pd = π //地址;

cout << pd; //地址,输出的是pd存储的地址,即pi的地址;
cout <<*pd;// 值,输出pd存储的地址所指向的元素的值,即pi的值3.14;

  1. 数组名

在非字符串数组的情况下,C++将数组没那个视为数组的第一个元素的地址, 即array = &array[0];

int array[20];  
`cout << sizeof(array);` //返回整个数组的长度;
`cout << sizeof(pointer)` // 返回指针所占存储空间大小

cout << array

// 数组名被解释为第一个元素的地址;等价于&array[0], 得到的是一个四字节内存块的地址;
//array+1 将地址值+4;
// array 可视为一个int指针(*int);

cout << &array
//得到的是整个数组的地址,一个20*4 =80字节内存块的地址;
//&array+1 将地址加80;
// &array可视作一个数组指针;

  1. 指针算术

指针和整数相加,等于在原来的地址值上加上指向的对象占用的总字节数。double 指针+1,指针数值增加8;
两个指向同一数组的指针相减,得到的是两个指针之间的元素个数

int tacos[10] = {0,1,2,3,4,5,6,7,8,9};
int *pt = tacos;
pt =pt +1;  // pt存储/指向tacos[1],即1; 

// tacos = tacos +1  是非法的;

int *pe =&tacos[9]; 
pe =pe -1; //指向tacos[8];
int diff = pe -pt;  // diff 为7 tacos[8]和tacos[1]差了7个元素;
  1. 数组的动态联编和静态联编;

静态联编:通过数组声明创建数组,即数组的长度在编译时确定;
动态联编(动态数组):使用new[]运算符创建数组,即在运行时为数组分配空间,其长度也将在运行时设置。使用后,应使用delete[]释放所占用的内存;
int size;
cin >> size;
int *pz = new int [size];

delete [] pz;

  1. 数组表示法和指针表示法

c++ 将数组名解释为地址(首元素地址,数组地址);

tacos[1] == *(tacos + 1)  == *(pt +1) == pt[1]; 

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

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

相关文章

Python编码规范与常见问题纠正

Python编码规范与常见问题纠正 Python 是一种以简洁和易读性著称的编程语言&#xff0c;因此&#xff0c;遵循良好的编码规范不仅能使代码易于维护&#xff0c;还能提升代码的可读性和可扩展性。编写规范的 Python 代码也是开发者职业素养的一部分&#xff0c;本文将从 Python…

Linux聊天集群开发之环境准备

一.windows下远程操作Linux 第一步&#xff1a;在Linux终端下配置openssh&#xff0c;输入netstate -tanp,查看ssh服务是否启动&#xff0c;默认端口22.。 注&#xff1a;如果openssh服务&#xff0c;则需下载。输入命令ps -e|grep ssh, 查看如否配有&#xff0c; ssh-agent …

tensorflow快速入门--如何定义张量、定义网络结构、超参数设置、模型训练???

前言 由于最近学习的东西涉及到tensorflow的使用&#xff0c;故先简单的学习了一下tensorflow中如何定义张量、定义网络结构、超参数设置、模型训练的API调用过程&#xff1b;欢迎大家&#xff0c;收藏关注&#xff0c;本人将持续更新。 文章目录 1、基本操作1、张量基础操作创…

[Python] 编程入门:理解变量类型

文章目录 [toc] 整数常见操作 浮点数字符串字符串中混用引号问题字符串长度计算字符串拼接 布尔类型动态类型特性类型转换结语 收录专栏&#xff1a;[Python] 在编程中&#xff0c;变量是用于存储数据的容器&#xff0c;而不同的变量类型则用来存储不同种类的数据。Python 与 C…

爬虫——爬虫理论+request模块

一、爬虫理论 爬虫——请求网站并提取数据的自动化程序 网络爬虫&#xff08;又被称为网页蜘蛛&#xff0c;网络机器人&#xff09;就是模拟客户端发送网络请求&#xff0c;接收请求响应&#xff0c;一种按照一定的规则&#xff0c;自动的抓取互联网信息的程序。 原则上&…

SQL第12课——联结表

三点&#xff1a;什么是联结&#xff1f;为什么使用联结&#xff1f;如何编写使用联结的select语句 12.1 联结 SQL最强大的功能之一就是能在数据查询的执行中联结&#xff08;join)表。联结是利用SQL的select能执行的最重要的操作。 在使用联结前&#xff0c;需要了解关系表…

【数据结构 | PTA】栈

文章目录 7-1 汉诺塔的非递归实现7-2 出栈序列的合法性**7-3 简单计算器**7-4 盲盒包装流水线 7-1 汉诺塔的非递归实现 借助堆栈以非递归&#xff08;循环&#xff09;方式求解汉诺塔的问题&#xff08;n, a, b, c&#xff09;&#xff0c;即将N个盘子从起始柱&#xff08;标记…

Golang | Leetcode Golang题解之第447题回旋镖的数量

题目&#xff1a; 题解&#xff1a; func numberOfBoomerangs(points [][]int) (ans int) {for _, p : range points {cnt : map[int]int{}for _, q : range points {dis : (p[0]-q[0])*(p[0]-q[0]) (p[1]-q[1])*(p[1]-q[1])cnt[dis]}for _, m : range cnt {ans m * (m - 1)…

多功能快捷回复软件

各位亲爱的客服宝宝们&#xff0c;每天面对大量的客户咨询&#xff0c;您是否还在手动一个一个地打字回复呢&#xff1f;别担心&#xff0c;我们为您带来了一款多功能快捷回复软件——客服宝。有了它&#xff0c;您的工作将变得无比轻松&#xff01; 客服宝是一款集成了内容存储…

window下‘jps‘ 不是内部或外部命令,也不是可运行的程序或批处理文件,特别是使用idea开发工具的环境

1、在系统环境变量里面查看是否有JAVA_HOME环境变量&#xff0c;如果是用idea来管理环境变量的&#xff0c;需要如图设置指向jbr&#xff0c;如果是单独安装的jdk环境指向自己的安装目录即可 2、设置系统环境Path&#xff0c;需要把jre和bin添加进去

手写mybatis之把反射用到出神入化

前言 但在实操上&#xff0c;很多码农根本没法阅读框架源码。首先一个非常大的问题是&#xff0c;面对如此庞大的框架源码&#xff0c;不知道从哪下手。与平常的业务需求开发相比&#xff0c;框架源码中运用了大量的设计原则和设计模式对系统功能进行解耦和实现&#xff0c;也使…

深度学习----------------------序列到序列学习(seq2seq)

目录 机器翻译Seq2seq编码器-解码器细节训练衡量生成序列的好坏的BLEU总结序列到序列学习实现循环神经网络编码器解码器通过零值化屏蔽不相关的项该部分总代码 通过扩展softmax交叉熵损失函数来遮蔽不相关的预测训练预测BLEU的代码实现该部分总代码 机器翻译 给定一个源语言的…

IDEA几大常用AI插件

文章目录 前言列表GPT中文版TalkXBito AIIDEA自带的AI 前言 最近AI、GPT特别火&#xff0c;IDEA里面又有一堆插件支持GPT&#xff0c;所以做个专题比较一下各个GPT插件 列表 先看idea的plugins里支持哪些&#xff0c;搜索“GPT”之后得到的&#xff0c;我用下来感觉第一第二和…

使用微服务Spring Cloud集成Kafka实现异步通信(消费者)

1、本文架构 本文目标是使用微服务Spring Cloud集成Kafka实现异步通信。其中Kafka Server部署在Ubuntu虚拟机上&#xff0c;微服务部署在Windows 11系统上&#xff0c;Kafka Producer微服务和Kafka Consumer微服务分别注册到Eureka注册中心。Kafka Producer和Kafka Consumer之…

无法编辑PDF文件?试试这3个解决方法!

PDF文件格式广泛应用于工作中&#xff0c;但有时候我们可能遇到无法编辑PDF文件的情况。这可能导致工作效率降低&#xff0c;特别是在需要修改文件内容时显得尤为棘手。遇到PDF不能编辑时&#xff0c;可以看看是否以下3个原因导致的。 原因一&#xff1a;PDF文件设置了编辑权限…

dockertop提示Failed to fetch extensions

解决办法&#xff1a;重装dockertop 第一步&#xff1a;卸载当前的dockertop 如果卸载过程中存在AlibabaProtect的相关软件关不掉&#xff0c;那么参考这篇文章&#xff1a;卸载AlibabaProtect 第二步&#xff1a;删除C:\Program Files路径下的Docker文件夹 第三步&#xff1…

YOLOv5复现(论文复现)

YOLOv5复现&#xff08;论文复现&#xff09; 本文所涉及所有资源均在传知代码平台可获取 文章目录 YOLOv5复现&#xff08;论文复现&#xff09;概述模型结构正负样本匹配策略损失计算数据增强使用方式训练测试验证Demo 概述 YOLOv5是由Ultralytics公司于2020年6月开源的目标检…

【架构】prometheus+grafana系统监控

文章目录 一、Prometheus简介二、Grafana简介三、PrometheusGrafana系统监控的实现四、优势与应用场景 参考 PrometheusGrafana系统监控是一个强大的组合&#xff0c;用于实时监控和分析系统的性能与状态。以下是对这一组合在系统监控中的详细解析&#xff1a; 一、Prometheus…

【牛顿迭代法求极小值】

牛顿迭代法求极小值 仅供参考 作业内容与要求 作业内容 作业要求 递交报告 代码 编程实现 计算偏导数 故上述非线性方程组的根可能为 f ( x , y ) f(x, y) f(x,y)的极值点&#xff0c;至于是极小值点还是极大值点或鞍点&#xff0c;就需要使用微积分中的黑塞矩阵来判断了。…

避雷!Google Adsense联盟营销七大投放误区

你是否在使用Google AdSense进行广告投放&#xff1f;你是否想进一步优化你的投放策略&#xff1f;那么这篇文章你不可错过啦&#xff01; Google AdSense为跨境商家提供了一个平台&#xff0c;我们可以通过展示相关广告来赚取收入。然而&#xff0c;即使是最有经验的商家也可…