C++ Primer 中文版 第5版 读书笔记

读书过程中发现,读得越多,忘得越多。因此记录读书笔记

1.2 初始输入输出

向流写入数据

<<运算符(输出运算符)接受两个运算对象:左侧的运算对象必须是一个ostream对象,右侧的运算对象是要打印的值。此运算符将给定的值写到给定的ostream对象中。输出运算符的计算结果就是其左侧运算对象。即,计算结果就是我们写入给定值的那个ostream对象。

std::cout<<"Enter two numbers:"<<std::endl;
// 等价于
(std::cout<<"Enter two numbers:")<<std::endl;

第一个输出运算符给用户打印一条消息。这个消息是一个字符串字面值常量(stringliteral),是用一对双引号包围的字符序列。在双引号之间的文本被打印到标准输出。
第二个运算符打印endl,这是一个被称为操纵符(manipulator)的特殊值。写入endl的效果是结束当前行,并将与设备关联的缓冲区(buffer)中的内容刷到设备中。缓冲刷新操作可以保证到目前为止程序所产生的所有输出都真正写入输出流中,而不是仅停留在内存中等待写入流。
在这里插入图片描述

1.4.3 读取数量不定的输入数据

int a = 0;
while (std::cin >> a)
{// todo
}

while (std::cin >> a)此表达式从标准输入读取下一个数,保存在value中。输入运算符返回其左侧运算对象。因此,此循环条件实际上检测的是std::cin。当我们使用一个istream对象作为条件时,其效果是检测流的状态。如果流是有效的,即流未遇到错误,那么检测成功。当遇到文件结束符(end-of-file),或遇到一个无效输入时(例如读入的值不是一个整数),istream对象的状态会变为无效

2.1 基本内置类型

2.1.1 算术类型在这里插入图片描述

2.1.3 字面值常量

转义序列

在这里插入图片描述
在这里插入图片描述
对于一个整型字面值来说,我们能分别指定它是否带符号以及占用多少空间。如果后缀中有U,则该字面值属于无符号类型,也就是说,以U为后缀的十进制数、八进制数或十六进制数都将从unsigned int、unsigned long和unsigned long long中选择能匹配的空间最小的一个作为其数据类型。如果后缀中有L,则字面值的类型至少是long;如果后缀中有LL,则字面值的类型将是long long和unsigned long long中的一种。显然我们可以将U与L或LL合在一起使用。例如,以UL为后缀的字面值的数据类型将根据具体数值情况或者取unsigned long,或者取unsigned long long。
在这里插入图片描述
在这里插入图片描述

列表初始化

在这里插入图片描述

2.2.2 变量声明和定义的关系

分离式编译
如果想声明一个变量而非定义它,就在变量前添加关键字extern,而且不要显示地初始化变量:

extern int i;	// 声明i,而非定义i
int j;		// 声明并定义j

任何包含了显示初始化的声明即成为定义。我们能给由extern关键字标记的变量赋一个初始值,但是这么做也就抵消了extern的作用。extern语句如果包含初始值就不再时声明,而变成了定义:

extern double pi = 3.14159;		// 定义

变量能且只能被定义一次,但是可以多次声明

2.3.1 引用

在这里插入图片描述

2.3.2 指针

void* 指针

void* 是一种特殊的指针类型,可用于存放任意对象的地址。一个void*指针存放着一个地址,这点和其他指针类似。不同的是,我们对指针中到底是个什么类型的数据并不了解

double obj = 3.14, *pd = &obj;	// 正确:void* 可以存放任意类型对象的地址void *pv = &obj;		// obj可以是任意对象的类型
pv = pd;

利用void*指针能做的事儿比较有限:拿它和别的指针比较、作为函数的输入或输出,或者赋给另外一个void*指针,或者进行强制类型转换。不能直接操作void*指针所指的对象,因为我们并不知道这个对象到底是什么类型,也就无法确定能在这个对象上做哪些操作。概括说来,以void*的视角来看内存空间也就仅仅是内存空间,没办法访问内存空间中所存的对。

指向指针的指针

一般来说,声明符中修饰符的个数并没有限制。当有多个修饰符连写在一起时,按照其逻辑关系详加解释即可。以指针为例,指针是内存中的对象,像其他对象一样也有自己的地址,因此允许把指针的地址再存放到另一个指针当中。通过*的个数可以区分指针的级别。也就是说,**表示指向指针的指针,***表示指向指针的指针的指针,以此类推:
在这里插入图片描述

指向指针的引用

在这里插入图片描述
要理解r的类型到底是什么,最简单的办法是从右向左阅读r的定义。离变量名最近的符号(此例中是&r的符号。)对变量的类型有最直接的影响,因此r是一个引用。声明符的其余部分用以确定r引用的类型是什么,此例中的符号*说明r引用的是一个指针。最后,声明的基本数据类型部分指出r引l用的是一个int指针。
在这里插入图片描述

2.4 const限定符

有时我们希望定义这样一种变量,它的值不能被改变。例如,用一个变量来表示缓冲区的大小。使用变量的好处是当我们觉得缓冲区大小不再合适时,很容易对其进行调整。另一方面,也应随时警惕防止程序一不小心改变了这个值。为了满足这一要求,可以用关键字const对变量的类型加以限定:

const int bufSize =512;//输入缓冲区大小const int i=get size();	//正确:运行时初始化
const int j=42;	//正确:编译时初始化
const int k;	//错误:k是一个未经初始化的常量

在这里插入图片描述

2.4.1 const 的引用

可以把引用绑定到const 对象上,就像绑定到其他对象上一样,我们呢称之为对象常量的引用。与普通引用不同的是,对常量的引用不能被用作修改它所绑定的对象:

const int ci = 1024;
const int &r1 = ci;		// 正确:引用及其对应的对象都是常量r1 = 42;		// 错误:r1是对常量的引用
int &r2 = ci;	// 错误:图让一个非常量引用指向一个常量对象
初始化和对const的引用

在这里插入图片描述

对const的引用可能引用一个并非const的对象

在这里插入图片描述

2.4.4 constexpr 和常量表达式

常量表达式(constexpression)是指值不会改变并且在编译过程就能得到计算结果的表达式。显然,字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式。后面将会提到,C++语言中有几种情况下是要用到常量表达式的。
一个对象(或表达式)是不是常量表达式由它的数据类型和初始值共同决定,例如:

const int max_files = 20;	// max_files 是常量表达式
const int limit = max_files + 1;	// limit 是常量表达式
int staff_size = 27;		// staff_size 不是常量表达式
const int sz = get_size();	// sz不是常量表达式

尽管staffsize的初始值是个字面值常量,但由于它的数据类型只是一个普通int而非constint,所以它不属于常量表达式。另一方面,尽管sz本身是一个常量,但它的具体值直到运行时才能获取到,所以也不是常量表达式。

constexpr 变量

在一个复杂系统中,很难(几乎肯定不能)分辨一个初始值到底是不是常量表达式。当然可以定义一个const变量并把它的初始值设为我们认为的某个常量表达式,但在实际使用时,尽管要求如此却常常发现初始值并非常量表达式的情况。可以这么说,在此种情况下,对象的定义和使用根本就是两回事儿。
C++11新标准规定,允许将变量声明为constexpr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化:

constexpr int mf = 20;	// 20是常量表达式
constexpr int limit = mf + 1;	// 是常量表达式
constexpr int sz  = size();		// 只有当size是一个constexpr函数时,才是一条正确的声明语句

尽管不能使用普通函数作为constexpr变量的初始值,但是正如6.5.2节(第214页)将要介绍的,新标准允许定义一种特殊的constexpr函数。这种函数应该足够简单以使得编译时就可以计算其结果,这样就能用constexpr函数去初始化constexpr变量了。
在这里插入图片描述

指针和constexpr

必须明确一点,在constexpr声明中如果定义了一个指针,限定符constexpr仅对指针有效(相当于底层const),与指针所指的对象无关:

const int *p=nullptr;	//p是一个指向整型常量的指针
constexpr int *g=nullptr;	//g是一个指向整数的常量指针

p和g的类型相差甚远,p是一个指向常量的指针,而g是一个常量指针,其中的关键在于constexpr把它所定义的对象置为了顶层const(参见2.4.3节,第57页)。

2.5.1 类型别名

类型别名(typealias)是一个名字,它是某种类型的同义词。使用类型别名有很多好处,它让复杂的类型名字变得简单明了、易于理解和使用,还有助于程序员清楚地知道使用该类型的真实目的。有两种方法可用于定义类型别名。传统的方法是使用关键字typedef

typedef double wages;		//wages是double的同义词
typedef wages base,*p;		//base是double的同义词,p是double*的同义词

基本类型和复合类型均可使用
新标准规定了一种新的方法,使用别名声明(aliasdeclaration)来定义类型的别名:

using SI=Sales_item;		//SI是Sales_item的同义词
2.5.2 auto 类型说明符

编程时常常需要把表达式的值赋给变量,这就要求在声明变量的时候清楚地知道表达式的类型。然而要做到这一点并非那么容易,有时甚至根本做不到。为了解决这个问题,C++11新标准引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型。和原来那些只对应一种特定类型的说明符(比如double)不同,auto让编译器通过初始值来推算变量的类型。显然,auto定义的变量必须有初始值:

//由val1和val2相加的结果可以推断出item的类型
auto item = val1 + val2;	//item初始化为val1和val2相加的结果

使用auto也能在一条语句中声明多个变量。因为一条声明语句只能有一个基本数据类型,所以该语句中所有变量的初始基本数据类型都必须一样:

auto i = 0*p = &i;	//正确:i是整数、p是整型指针
auto sz = 0,pi = 3.14;	//错误:sz和pi的类型不一致

auto一般会忽略掉顶层const,同时底层const则会保留下来,比如当初始值是一个指向常量的指针时:

const int ci = i;
auto b = ci;	// b 的类型是int

如果希望推断出的auto类型是一个顶层const,需要明确指出:

const auto f = ci;//ci的推演类型是int,f是constint

还可以将引用的类型设为auto,此时原来的初始化规则仍然适用:

auto &g = ci;	//g是一个整型常量引用,绑定到ci
auto &h = 42;	//错误:不能为非常量引用绑定字面值
const auto &j =42;	//正确:可以为常量引用绑定字面值

decltype 类型指示符

有时会遇到这种情况:希望从表达式的类型推断出要定义的变量的类型,但是不想用该表达式的值初始化变量。为了满足这一要求,C++11新标准引入了第二种类型说明符decltype,它的作用是选择并返回操作数的数据类型。在此过程中,编译器分析表达式并得到它的类型,却不实际计算表达式的值:

decltype(f()) sum = x;		//sum的类型就是函数f的返回类型

编译器并不实际调用函数f,而是使用当调用发生时f的返回值类型作为sum的类型。换句话说,编译器为sum指定的类型是什么呢?就是假如f被调用的话将会返回的那个类型。

decltype处理顶层const和引l用的方式与auto有些许不同。如果decltype使用的表达式是一个变量,则decltype返回该变量的类型(包括顶层const和引用在内):

const int ci = 0, &cj = ci;
decltype(ci) x = 0;		// x 的类型是const int
decltype(cj) y = x;		// y 的类型是const int&,y 绑定到变量x
decltype 和引用

如果decltype使用的表达式不是一个变量,则decltype返回表达式结果对应的类型。如4.1.1节(第120页)将要介绍的,有些表达式将向decltype返回一个引用类型。一般来说当这种情况发生时,意味着该表达式的结果对象能作为一条赋值语句的左值:

//decltype的结果可以是引用类型
int i = 42, *p = &i,&r = i;
decltype(r+0) b;	//正确:加法的结果是int,因此b是一个(未初始化的)int
decltype(*p)c;		//错误:c是int&,必须初始化

因为r是一个引用,因此decltype(r)的结果是引用类型。如果想让结果类型是r所指的类型,可以把r作为表达式的一部分,如r+0,显然这个表达式的结果将是一个具体值而非一个引用。
另一方面,如果表达式的内容是解引用操作,则decltype将得到引用类型。正如我们所熟悉的那样,解引用指针可以得到指针所指的对象,而且还能给这个对象赋值。因此,decltype(*p)的结果类型就是int&,而非int。
**decltype和auto的另一处重要区别是,decltype的结果类型与表达式形式密切相关。**有一种情况需要特别注意:对于decltype所用的表达式来说,如果变量名加上了一对括号,则得到引用:

//decltype的表达式如果是加上了括号的变量,结果将是引用
decltype((i)) d;		// 错误: d是int&,必须初始化

在这里插入图片描述

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

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

相关文章

Vatee万腾平台:一站式智慧服务,让生活更美好

在数字化浪潮席卷全球的今天&#xff0c;我们生活的方方面面都在经历着前所未有的变革。Vatee万腾平台凭借其一站式智慧服务&#xff0c;正成为推动这场变革的重要力量&#xff0c;让我们的生活变得更加美好。 Vatee万腾平台&#xff0c;作为一家专注于提供智慧服务的领军企业&…

基于weixin小程序校园快递系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;用户管理&#xff0c;订单管理&#xff0c;快递管理&#xff0c;快递记录管理&#xff0c;公告管理&#xff0c;基础数据管理 小程序功能包括&#xff1a;系统首页&#xff0c;…

企业有必要安装数据文件加密软件吗?哇!这么多好处

需要的 一、查看以下分析&#xff0c;便能得出结论 安全防护提升&#xff1a;禁止拷贝、打印、截屏等&#xff0c;还能够设置文件的浏览次数、有效期&#xff0c;提供多层次的文档保护措施。 核心机密保护&#xff1a;企业的核心机密文件、技术资料、客户资料等重要信息是公…

reactjs18 中使用@reduxjs/toolkit同步异步数据的使用

react18 中使用@reduxjs/toolkit 1.安装依赖包 yarn add @reduxjs/toolkit react-redux2.创建 store 根目录下面创建 store 文件夹,然后创建 index.js 文件。 import {configureStore } from "@reduxjs/toolkit"; import {counterReducer } from "./feature…

Does a vector database maintain pre-vector chunked data for RAG systems?

题意&#xff1a;一个向量数据库是否为RAG系统维护预向量化分块数据&#xff1f; 问题背景&#xff1a; I believe that when using an LLM with a Retrieval-Augmented Generation (RAG) approach, the results retrieved from a vector search must ultimately be presented…

WIFI各版本的带宽

带宽的定义&#xff1a; 带宽在网络领域通常指信道带宽&#xff0c;即信号在频谱中占用的频宽&#xff0c;单位是MHz&#xff08;兆赫&#xff09;。在无线通信中&#xff0c;带宽越宽&#xff0c;能够传输的数据量越大&#xff0c;因此信道带宽直接影响着数据传输速率。WiFi标…

FairGuard游戏加固无缝兼容 Android 15 预览版

2024年6月25日&#xff0c;谷歌发布了 Android 15 Beta 3 &#xff0c;作为Android 15 “平台稳定性”的里程碑版本&#xff0c;谷歌建议所有应用、游戏、SDK、库和游戏引擎开发者都将“平台稳定性”里程碑版本作为规划最终兼容性测试和公开发布的目标。 安卓开发者博客提供的版…

【2024-热-办公软件】ONLYOFFICE8.1版本桌面编辑器测评

在今日快速发展的数字化办公环境中&#xff0c;选择一个功能全面且高效的办公软件是至关重要的。最近&#xff0c;我有幸体验了ONLYOFFICE 8.1版本的桌面编辑器&#xff0c;这款软件不仅提供了强大的编辑功能&#xff0c;还拥有众多改进&#xff0c;让办公更加流畅和高效。在本…

货运大模型的未来:轻量化、场景化

“加快数字化和智能化转型发展&#xff0c;已成为物流行业的重要战略方向。”6月25日&#xff0c;在第十九届中国国际物流节暨第二十一届中国国际运输与物流博览会&2024亚洲物流双年展在上海开幕&#xff0c;中国交通运输协会会长、原铁道部副部长胡亚东在开幕致辞中表示。…

Python实践项目讲解:如何用制作一个桌面宠物

制作一个桌面宠物&#xff08;Desktop Pet&#xff09;在Python中通常涉及多个步骤&#xff0c;包括创建宠物的图形界面、添加动画效果、处理用户交互等。下面是一个简化的步骤指南&#xff0c;帮助你开始使用Python制作桌面宠物&#xff1a; 选择图形库&#xff1a; Tkinter&…

新能源行业必会基础知识-----电力市场概论笔记-----绪论

新能源行业知识体系-------主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/139946830 目录 1. 电力市场的定义2. 对传统电力系统理论的挑战 1. 电力市场的定义 1. 我国电力市场的进程 我国新一轮电力体制改革的5大亮点&…

【Echarts】散点图 制作 气泡 类型图表

目录 需求主要代码效果展示注 需求 需参照设计图画出对应图表 主要代码 /**** 数据 ****/ this.dataList [...Array(8).keys()].map((item) > {return {ywlxmc: 业务类型 (item 1),sl: item > 4 ? 50 : 70} })/**** 气泡样式 ****/ const styleList [{offset: [56…

NVIDIA控制面板3D设置一栏中不能通过预览更改图形设置的解决办法

今天因为GeForce Experience弹窗让我更新之后&#xff0c;手欠直接删掉了 然后图中标出的两个选项就没了 解决方法很简单&#xff0c;就是下回来&#xff0c;hhh https://www.nvidia.cn/geforce/drivers/ 直接下载就行&#xff0c;不用管版本&#xff0c;但是这种驱动千万不要…

U盘提示格式化怎么搞定?本文有5种方法(内含教程)

U盘提示格式化是一种常见故障&#xff0c;即&#xff1a;当U盘插入电脑后&#xff0c;电脑上弹出对话框&#xff0c;提示该U盘需要格式化才能使用。 接触不良、文件系统损坏、热插拔、感染病毒、芯片损坏等原因都可能导致U盘出现此故障。这时点击“格式化”&#xff0c;大概率会…

蒸汽架空管道中的关键守护者:滑动管托、导向管托与固定管托

蒸汽架空管道中的关键守护者&#xff1a;滑动管托、导向管托、固定管托与补偿器的重要角色在蒸汽架空管道系统中&#xff0c;每一个组件都扮演着不可或缺的角色&#xff0c;共同确保管道的安全、高效运行。今天&#xff0c;我们就来深入探讨滑动管托、导向管托、固定管托以及补…

武汉星起航:深度洞察消费趋势,亚马逊美国站选品独具匠心

亚马逊美国站作为全球电商巨头的重要分支&#xff0c;其选品特点不仅反映了美国市场的消费趋势&#xff0c;更引领着全球消费者的购物潮流。从运动户外、宠物用品到美容个人护理&#xff0c;亚马逊美国站的选品策略始终紧跟市场脉搏&#xff0c;为消费者提供丰富多样、品质优良…

简化收支记录,只留关键日期! 一键掌握财务流动,高效管理您的每一笔收支

在繁忙的生活中&#xff0c;管理个人或家庭的财务收支变得尤为重要。然而&#xff0c;传统的记账方式往往繁琐且复杂&#xff0c;让人望而却步。今天&#xff0c;我们为您推荐一款简洁易用的记账神器——晨曦记账本&#xff0c;让您轻松记录收支&#xff0c;只显示日期&#xf…

揭秘!这款电路设计工具让学校师生都爱不释手——SmartEDA的魔力何在?

随着科技的飞速发展&#xff0c;电子设计已成为学校师生们不可或缺的技能之一。而在众多的电路设计工具中&#xff0c;有一款名为SmartEDA的工具&#xff0c;凭借其强大的功能和友好的用户体验&#xff0c;迅速赢得了广大师生的青睐。今天&#xff0c;就让我们一起探索SmartEDA…

Leetcode TOP5 题目和解答:这里只提供一种解题思路,希望引导大家持续学习,可以采用FlowUs息流记录自己的学习

LeetCode 是一个在线编程平台&#xff0c;它提供了大量的算法题目供用户练习。 TOP5题目通常指的是 LeetCode 网站上最受欢迎的前5道题目。 以下是 LeetCode TOP5 题目的列表以及它们常见的解题思路和代码示例。 题目1 两数之和 两数之和 - 1. Two Sum Given an array of int…

html5 video去除边框

video的属性&#xff1a; autoplay 视频在就绪后自动播放。 controls 显示控件&#xff0c;比如播放按钮。 height 设置视频播放器的高度。 width 设置视频播放器的宽度。 loop 循环播放 muted 视频的音频输出静音。 poster 视频加载时显示的图像&#xff0c;或者在用户点击播…