【C++ Primer Plus】4

news2024/11/23 11:57:44

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表示存储在该地址出的值。

指针的定义:type *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;

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

  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]; 

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

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

相关文章

网 络 安 全

网络安全是指保护网络系统及其所存储或传输的数据免遭未经授权访问、使用、揭露、破坏、修改或破坏的实践和技术措施。网络安全涉及多个方面&#xff0c;包括但不限于以下几个方面&#xff1a; 1. 数据保护&#xff1a;确保数据在传输和存储过程中的完整性和保密性&#xff0c;…

微服务es+Kibana解析部署使用全流程

1、介绍 ElasticSearch是Java开发的一款开源的&#xff0c;分布式的搜索引擎。 它的搜索采用内存中检索的方式&#xff0c;大大提高了检索的效率&#xff0c;es是基于REST API的方式对数据操作的&#xff0c;可以让存储、检索、索引效率更高。 1、es可以做什么 网站检索数据…

python爬虫 - 深入requests模块

&#x1f308;个人主页&#xff1a;https://blog.csdn.net/2401_86688088?typeblog &#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/2401_86688088/category_12797772.html 目录 ​编辑 前言 一、下载网络文件 &#xff08;一&#xff09;基本步骤 &#xff0…

【AIGC】如何选择AI绘画工具?Midjourney VS Stable Diffusion

前言 文章目录 &#x1f4af;如何选择合适的AI绘画工具 个人需求选择比较工具特点社区和资源 &#x1f4af; Midjourney VS Stable Diffusion&#xff1a;深度对比与剖析 使用费用对比使用便捷性与系统兼容性对比开源与闭源对比图片质量对比上手难易对比学习资源对比作品版权问…

Vue入门-指令学习-v-else和v-else-if

v-else和v-else-if 作用&#xff1a;辅助v-if进行判断渲染 语法&#xff1a;v-else v-else-if"表达式" 注意&#xff1a;需要紧挨着v-if一起使用 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><m…

九大排序之插入排序

1.前言 插入排序是把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中&#xff0c;直到所有的记录插入完为止&#xff0c;得到一个新的有序序列 。实际中我们玩扑克牌时&#xff0c;就用了插入排序的思想。 本章重点&#xff1a;主要着重的介绍两种插入排序…

【JavaEE】【多线程】进程与线程的概念

目录 进程系统管理进程系统操作进程进程控制块PCB关键属性cpu对进程的操作进程调度 线程线程与进程线程资源分配线程调度 线程与进程区别线程简单操作代码创建线程查看线程 进程 进程是操作系统对一个正在运行的程序的一种抽象&#xff0c;可以把进程看做程序的一次运行过程&a…

开发自定义starter

环境&#xff1a;Spring Cloud Gateway 需求&#xff1a;防止用户绕过网关直接访问服务器&#xff0c;用户只需引入依赖即可。 1、创建项目 首先创建一个spring boot项目 2、配置pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xm…

国外电商系统开发-运维系统文件上传

文件上传&#xff0c;是指您把您当前的PC电脑上的文件批量的上传到远程服务器上&#xff0c;在这里&#xff0c;您可以很轻松的通过拖动方式上传&#xff0c;只需要动动鼠标就搞定。 第一步&#xff0c;您应该选择要上传的服务器&#xff1a; 选择好了以后&#xff0c;点击【确…

SpringBoot框架下的教育系统开发全解析

1系统概述 1.1 研究背景 随着计算机技术的发展以及计算机网络的逐渐普及&#xff0c;互联网成为人们查找信息的重要场所&#xff0c;二十一世纪是信息的时代&#xff0c;所以信息的管理显得特别重要。因此&#xff0c;使用计算机来管理微服务在线教育系统的相关信息成为必然。开…

毕业设计项目——基于transformer的中文医疗领域命名实体识别(论文/代码)

完整的论文代码见文章末尾 以下为核心内容 摘要 近年来&#xff0c;随着深度学习技术的发展&#xff0c;基于Transformer和BERT的模型在自然语言处理领域取得了显著进展。在中文医疗领域&#xff0c;命名实体识别(Named Entity Recognition, NER)是一项重要任务&#xff0c;旨…

ArkUI中的状态管理

一、MVVM ArkUI提供了一系列装饰器实现ViewModel的能力,如@Prop、@Link、@Provide、LocalStorage等。当自定义组件内变量被装饰器装饰时变为状态变量,状态变量的改变会引起UI的渲染刷新。 在ArkUI的开发过程中,如果没有选择合适的装饰器或合理的控制状态更新范围,可能会导…

《大规模语言模型从理论到实践》第一轮学习笔记

第一章 绪论 本章主要介绍大规模语言模型基本概念、发展历程和构建流程。 大规模语言模型&#xff08;Large Language Models&#xff0c;LLM&#xff09;&#xff0c;也称大语言模型 或大型语言模型。 1.1 大规模语言模型基本概念 1.语言模型&#xff08;Language Model&a…

重学SpringBoot3-集成Redis(五)之布隆过滤器

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;五&#xff09;之布隆过滤器 1. 什么是布隆过滤器&#xff1f;基本概念适用场景 2. 使用 Redis 实现布隆过滤器项目依赖Redis 配置…

Spring开发最佳实践之跨域处理

1. 跨域处理 1.1 异常现象 1.2 异常原因分析 跨源资源共享的官方定义如下&#xff1a; 跨源资源共享&#xff08;CORS&#xff0c;Cross Origin Resource Sharing。或通俗地译为跨域资源共享&#xff09;是一种基于 HTTP 头的机制&#xff0c;该机制通过允许服务器标示除了它自…

上海理工大学《2023年+2019年867自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《上海理工大学867自控考研资料》的真题篇。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2023年真题 2019年真题 Part1&#xff1a;2023年2019年完整版真题 2023年真题 2019年…

Java使用线程池创建线程

一、线程前言 首先我们知道&#xff0c;线程的概念如果不知道可以去看这一篇Java中的线程&#xff0c;我们这篇主要讲述的是Java怎么使用线程池创建线程&#xff0c;首先我们要对线程池有点概念&#xff0c;其实顾名思义&#xff0c;线程池就是有喝多线程的一个池子类似于&…

一书讲透LLM大语言模型,《掌握大型语言模型》,看完我都懵了!

《掌握大型语言模型》 &#xff08;Mastering Large Language Models&#xff09;由Sanket Subhash Khandare撰写&#xff0c;是一本关于大型语言模型&#xff08;LLMs&#xff09;的高级技术、应用、前沿方法和顶尖模型的指南。 这本大模型书已经上传CSDN&#xff0c;朋友们如…

《Windows PE》4.2 绑定导入表

绑定导入表&#xff08;Bound Import Table&#xff09;是文件中的一个数据结构&#xff0c;用于存储已经绑定&#xff08;即完成绑定导入&#xff09;的外部函数的信息。 本节必须掌握的知识点&#xff1a; 绑定导入表数据结构 实例分析 4.2.1 绑定导入表数据结构 绑定导入…

【AIGC】ChatGPT是如何思考的:探索CoT思维链技术的奥秘

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;什么是CoT思维链CoT思维链的背景与技术发展需求 &#x1f4af;CoT思维链的工作原理&#x1f4af;CoT思维链的应用领域&#x1f4af;CoT思维链的优势&#x1f4af;CoT思维…