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

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

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

相关文章

『网络游戏』自适应制作登录UI【01】

首先创建项目 修改场景名字为SceneLogin 创建一个Plane面板 - 将摄像机照射Plane 新建游戏启动场景GameRoot 新建空节点重命名为GameRoot 在子级下创建Canvas 拖拽EventSystem至子级 在Canvas子级下创建空节点重命名为LoginWnd - 即登录窗口 创建公告按钮 创建字体文本 创建输入…

Java:数据结构-初始结合框架 时间复杂度和空间复杂度 初识泛型

一 初始结合框架 1.什么是Java的集合框架 Java 的集合框架&#xff08;Java Collection Framework&#xff0c;JCF&#xff09;是 Java 标准库中的一部分&#xff0c;用于存储和操作一组数据。它提供了一些常用的数据结构和接口&#xff0c;用来高效管理和操作数据。Java 的…

TOP-K问题

目录 TOP-K问题 1.对TOP-K问题的理解 1.1.TOP-K问题定义 1.2.TOP-K问题的解决思路 1.3.以求N个数据中的前K个最大元素为例&#xff0c;阐述建堆来解决TOP-K的原理 1.4.TOP-K问题的类型 2.类型1&#xff1a;数据量N较小&#xff0c;可以全部加载到内存中。求数据量N的前K…

2024 ciscn WP

一、MISC 1.火锅链观光打卡 打开后连接自己的钱包&#xff0c;然后点击开始游戏&#xff0c;答题八次后点击获取NFT&#xff0c;得到有flag的图片 没什么多说的&#xff0c;知识问答题 兑换 NFT Flag{y0u_ar3_hotpot_K1ng} 2.Power Trajectory Diagram 方法1&#xff1a; 使用p…

集合论基础 - 离散数学系列(一)

目录 1. 集合的基本概念 什么是集合&#xff1f; 集合的表示方法 常见的特殊集合 2. 子集与幂集 子集 幂集 3. 集合的运算 交集、并集与补集 集合运算规则 4. 笛卡尔积 5. 实际应用 6. 例题与练习 例题1 练习题 总结 引言 集合论是离散数学的基础之一&#xff…

Linux 外设驱动 应用 1 IO口输出

从这里开始外设驱动介绍&#xff0c;这里使用的IMX8的芯片作为驱动介绍 开发流程&#xff1a; 修改设备树&#xff0c;配置 GPIO1_IO07 为 GPIO 输出。使用 sysfs 接口或编写驱动程序控制 GPIO 引脚。编译并测试。 这里假设设备树&#xff0c;已经配置好了。不在论述这个问题…

金融教育宣传月 | 平安养老险百色中心支公司开展金融知识“消保县域行”宣传活动

9月22日&#xff0c;平安养老险百色中心支公司积极落实国家金融监督管理总局关于开展金融教育宣传月活动的相关要求&#xff0c;联合平安人寿百色中心支公司共同组成了平安志愿者小队&#xff0c;走进百色市四塘镇百兰村开展了一场别开生面的金融消费者权益保护宣传活动。此次活…

通用mybatis-plus查询封装(QueryGenerator)

结果如下图所示 java类代码分别如下 1 package com.hdx.contractor.util.mybatis;import com.hdx.contractor.common.user.SecurityUser; import com.hdx.contractor.common.user.UserDetail; import com.hdx.contractor.util.query.oConvertUtils; import lombok.extern.slf…

YOLO11改进|卷积篇|引入线性可变形卷积LDConv

目录 一、【LDConv】卷积1.1【LDConv】卷积介绍1.2【LDConv】核心代码 二、添加【LDConv】卷积2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【LDConv】卷积 1.1【LDConv】卷积介绍 下图是【LDCNV】的结构图&#xff0c;让我们简单分析…

Ajax面试题:(第一天)

目录 1.说一下网络模型 2.在浏览器地址栏键入URL&#xff0c;按下回车之后会经历以下流程&#xff1a; 3.什么是三次握手和四次挥手&#xff1f; 4.http协议和https协议的区别 1.说一下网络模型 注&#xff1a;各层含义按自己理解即可 2.在浏览器地址栏键入URL&#xff0c;…

盲拍合约:让竞拍更公平与神秘的创新解决方案

目录 前言 一、盲拍合约是什么&#xff1f; 二、盲拍合约工作原理 1、合约创建与初始化 2、用户出价&#xff08;Bid&#xff09; 3、出价结束 4、披露出价&#xff08;Reveal&#xff09; 5、处理最高出价 6、结束拍卖 7、退款与提款 三、解析盲拍合约代码…

阿里云域名解析和备案

文章目录 1、域名解析2、新手引导3、ICP备案 1、域名解析 2、新手引导 3、ICP备案

类的特殊成员函数——三之法则、五之法则、零之法则

系统中的动态资源、文件句柄&#xff08;socket描述符、文件描述符&#xff09;是有限的&#xff0c;在类中若涉及对此类资源的操作&#xff0c;但是未做到妥善的管理&#xff0c;常会造成资源泄露问题&#xff0c;严重的可能造成资源不可用&#xff0c;如申请内存失败、文件句…

【redis-05】redis保证和mysql数据一致性

redis系列整体栏目 内容链接地址【一】redis基本数据类型和使用场景https://zhenghuisheng.blog.csdn.net/article/details/142406325【二】redis的持久化机制和原理https://zhenghuisheng.blog.csdn.net/article/details/142441756【三】redis缓存穿透、缓存击穿、缓存雪崩htt…

57.对称二叉树

迭代 class Solution {public boolean isSymmetric(TreeNode root) {if(rootnull){return true;}Deque<TreeNode> denew LinkedList<>();TreeNode l,r;int le;de.offer(root.left);de.offer(root.right);while(!de.isEmpty()){lde.pollFirst();rde.pollLast();if(…

BMC pam认证的使用

1.说明 1.1 文档参考资料 https://www.chiark.greenend.org.uk/doc/libpam-doc/html/Linux-PAM_ADG.htmlhttp://www.fifi.org/doc/libpam-doc/html/pam_appl-3.htmlpdf文档: https://fossies.org/linux/Linux-PAM-docs/doc/adg/Linux-PAM_ADG.pdflinux-pam 中文文档pam 旧文p…

<数据集>工程机械识别数据集<目标检测>

数据集格式&#xff1a;VOCYOLO格式 图片数量&#xff1a;2644张 标注数量(xml文件个数)&#xff1a;2644 标注数量(txt文件个数)&#xff1a;2644 标注类别数&#xff1a;3 标注类别名称&#xff1a;[dump truck, wheel loader, excavators] 序号类别名称图片数框数1dum…

SpringBootWeb快速入门!详解如何创建一个简单的SpringBoot项目?

在现代Web开发中&#xff0c;SpringBoot以其简化的配置和快速的开发效率而受到广大开发者的青睐。本篇文章将带领你从零开始&#xff0c;搭建一个基于SpringBoot的简单Web应用~ 一、前提准备 想要创建一个SpringBoot项目&#xff0c;需要做如下准备&#xff1a; idea集成开发…

wordpress Contact form 7发件人邮箱设置

此教程仅适用于演示站有留言的主题&#xff0c;演示站没有留言的主题&#xff0c;就别往下看了&#xff0c;免费浪费时间。 使用了Contact form 7插件的简站WordPress主题&#xff0c;在有人留言时&#xff0c;就会发邮件到网站的系统邮箱(一般与管理员邮箱为同一个)里。上面显…

SpringCloud简介 Ribbon Eureka 远程调用RestTemplate类 openfeign

〇、SpringCloud 0.区别于单体项目和soa架构&#xff0c;微服务架构每个服务独立&#xff0c;灵活。 1. spring cloud是一个完整的微服务框架&#xff0c;springCloud包括三个体系&#xff1a; spring cloud Netflix spring cloud Alibaba spring 其他 2.spring cloud 版本命名…