当前位置: 首页 > news >正文

C++ Primer Plus 第6版 读书笔记(6) 第 6 章 分支语句和逻辑运算符

第 6 章 分支语句和逻辑运算符

C++是在 C 语言基础上开发的一种集面向对象编程、泛型编程和过程化编程于一体的编程语言,是C语言的超集。本书是根据2003年的ISO/ANSI C++标准编写的,通过大量短小精悍的程序详细而全面地阐述了 C++的基本概念和技术,并专辟一章介绍了C++11新增的功能。
《C++ Primer Plus(第6版)中文版》分18章,分别介绍了C++程序的运行方式、基本数据类型、复合数据类型、循环和关系表达式、分支语句和逻辑运算符、函数重载和函数模板、内存模型和名称空间、类的设计和使用、多态、虚函数、动态内存分配、继承、代码重用、友元、异常处理技术、string类和标准模板库、输入/输出、C++11新增功能等内容。
《C++ Primer Plus(第6版)中文版》针对C++初学者,从C语言基础知识开始介绍,然后在此基础上详细阐述C++新增的特性,因此不要求读者有C语言方面的背景知识。《C++ Primer Plus(第6版)中文版》可作为高等院校教授C++课程的教材,也可供初学者自学C++时使用。

本章内容包括:if 语句。if else 语句。逻辑运算符:&&、||和!。cctype 字符函数库。条件运算符:?:。switch 语句。continue 和 break 语句。读取数字的循环。基本文件输入/输出。
 设计智能程序的一个关键是使程序具有决策能力。第 5 章介绍了一种决策方式——循环,在循环中,
程序决定是否继续循环。现在,来研究一下 C++是如何使用分支语句在可选择的操作中做出决定的。程序
应使用哪一种防止吸血鬼的方案(大蒜还是十字架)呢?用户选择了哪个菜单选项呢?用户是否输入了 0?
C++提供了 if 和 switch 语句来进行决策,它们是本章的主要主题。另外,还将介绍条件运算符和逻辑运算
符,前者提供了另一种决策方式,而后者允许将两个测试组合在一起。最后,本章将首次介绍文件输入/
输出。

在这里插入图片描述

6.1 if 语句

当 C++程序必须决定是否执行某个操作时,通常使用 if 语句来实现选择。if 有两种格式:if 和 if else。
首先看一看简单的 if,它模仿英语,如“If you have a Captain Cookie card, you get a free cookie(如果您有一
张 Captain Cookie 卡,就可获得免费的小甜饼)”。如果测试条件为 true,则 if 语句将引导程序执行语句或
语句块;如果条件是 false,程序将跳过这条语句或语句块。因此,if 语句让程序能够决定是否应执行特定
的语句。
if 语句的语法与 while 相似:
如果 test-condition(测试条件)为 true,则程序将执行 statement(语句),后者既可以是一条语
句,也可以是语句块。如果测试条件为 false,则程序将跳过语句(参见图 6.1)。和循环测试条件一
样,if 测试条件也将被强制转换为 bool 值,因此 0 将被转换为 false,非零为 true。整个 if 语句被视
为一条语句。
通常情况下,测试条件都是关系表达式,如那些用来控制循环的表达式。例如,假设读者希望程序计
算输入中的空格数和字符总数,则可以在 while 循环中使用 cin.get(char)来读取字符,然后使用 if 语句识
166 C++ Primer Plus(第 6 版)中文版
别空格字符并计算其总数。程序清单 6.1 完成了这项工作,它使用句点(.)来确定句子的结尾。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qZfLPCHs-1678173837043)(2023-03-06-18-53-41.png)]

### 6.1.1 if else 语句
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WMBeTVa0-1678173837044)(2023-03-06-19-09-01.png)]
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

条件运算符和错误防范

许多程序员将更直观的表达式 variable = =value 反转为 value = =variable,以此来捕获将相等运算符误
写为赋值运算符的错误。例如,下述条件有效,可以正常工作:

if (3 == myNumber)

但如果错误地使用下面的条件,编译器将生成错误消息,因为它以为程序员试图将一个值赋给一个字
面值(3 总是等于 3,而不能将另一个值赋给它):
if (3 = myNumber)

假设犯了类似的错误,但使用的是前一种表示方法:
if (myNumber = 3)

编译器将只是把 3 赋给 myNumber,而 if 中的语句块将包含非常常见的、而又非常难以发现的错误(然
而,很多编译器会发出警告,因此注意警告是明智的)。一般来说,编写让编译器能够发现错误的代码,比
找出导致难以理解的错误的原因要容易得多。

6.2 逻辑表达式

经常需要测试多种条件。例如,字符要是小写,其值就必须大于或等于’a’,且小于或等于’z’。如果要
求用户使用 y 或 n 进行响应,则希望用户无论输入大写(Y 和 N)或小写都可以。为满足这种需要,C++
提供了 3 种逻辑运算符,来组合或修改已有的表达式。这些运算符分别是逻辑 OR(||)、逻辑 AND(&&)
和逻辑 NOT(!)。下面介绍这些运算符。

6.2.1 逻辑 OR 运算符:||

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eJyXsdzF-1678173837044)(2023-03-06-19-17-11.png)]

6.2.2 逻辑 AND 运算符:&&

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2lzisQ7f-1678173837045)(2023-03-06-19-18-53.png)]

取值范围测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CIOvmENr-1678173837045)(2023-03-06-19-19-30.png)]

6.2.4 逻辑 NOT 运算符:!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aA4IHMVD-1678173837046)(2023-03-06-19-20-15.png)]

6.3 字符函数库 cctype

C++从 C 语言继承了一个与字符相关的、非常方便的函数软件包,它可以简化诸如确定字符是否为大
写字母、数字、标点符号等工作,这些函数的原型是在头文件 cctype(老式的风格中为 ctype.h)中定义的。
例如,如果 ch 是一个字母,则 isalpha(ch)函数返回一个非零值,否则返回 0。同样,如果 ch 是标点符
号(如逗号或句号),函数 ispunct(ch)将返回 true。(这些函数的返回类型为 int,而不是 bool,但通常 bool
转换让您能够将它们视为 bool 类型。)

使用这些函数比使用 AND 和 OR 运算符更方便。例如,下面是使用 AND 和 OR 来测试字符 ch 是不
是字母字符的代码:

与使用 isalpha( )相比:

isalpha( )不仅更容易使用,而且更通用。AND/OR 格式假设 A-Z 的字符编码是连续的,其他字符的编
码不在这个范围内。这种假设对于 ASCII 码来说是成立的,但通常并非总是如此。

程序清单 6.8 演示一些 ctype 库函数。具体地说,它使用 isalpha( )来检查字符是否为字母字符,使用
isdigits( )来测试字符是否为数字字符,如 3,使用 isspace( )来测试字符是否为空白,如换行符、空格和制
表符,使用 ispunct( )来测试字符是否为标点符号。该程序还复习了 if else if 结构,并在一个 while 循环中
使用了 cin.get(char)。

i[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xSH5jYPA-1678173837046)(2023-03-06-19-43-52.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ysol9paX-1678173837046)(2023-03-06-19-44-54.png)]

6.4 ?:运算符(三元运算符)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QFtRUExx-1678173837046)(2023-03-06-19-48-07.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-speOy706-1678173837047)(2023-03-06-20-19-53.png)]

6.5 switch 语句

假设要创建一个屏幕菜单,要求用户从 5 个选项中选择一个,例如,便宜、适中、昂贵、奢侈、过度。
虽然可以扩展 if else if else 序列来处理这 5 种情况,但 C++的 switch 语句能够更容易地从大型列表中进行
选择。下面是 switch 语句的通用格式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aoAQG3fJ-1678173837047)(2023-03-06-23-10-15.png)]

C++的 switch 语句就像指路牌,告诉计算机接下来应执行哪行代码。执行到 switch 语句时,程序将跳
到使用 integer-expression 的值标记的那一行。例如,如果 integer-expression 的值为 4,则程序将执行标签为
case 4:那一行。顾名思义,integer-expression 必须是一个结果为整数值的表达式。另外,每个标签都必须
是整数常量表达式。最常见的标签是 int 或 char 常量(如 1 或’q’),也可以是枚举量。如果 integer-expression

不与任何标签匹配,则程序将跳到标签为 default 的那一行。Default 标签是可选的,如果被省略,而又没
有匹配的标签,则程序将跳到 switch 后面的语句处执行(参见图 6.3)。
switch 语句与 Pascal 等语言中类似的语句之间存在重大的差别。C++中的 case 标签只是行标签,而不
是选项之间的界线。也是说,程序跳到 switch 中特定代码行后,将依次执行之后的所有语句,除非有明确
的其他指示。程序不会在执行到下一个 case 处自动停止,要让程序执行完一组特定语句后停止,必须使用
break 语句。这将导致程序跳到 switch 后面的语句处执行。

6.6 break 和 continue 语句

break 和 continue 语句都使程序能够跳过部分代码。可以在 switch 语句或任何循环中使用 break 语句,
使程序跳到 switch 或循环后面的语句处执行。continue 语句用于循环中,让程序跳过循环体中余下的代码,
并开始新一轮循环(参见图 6.4)。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fQKQfZAY-1678173837047)(2023-03-06-23-13-48.png)]

6.8 简单文件输入/输出

有时候,通过键盘输入并非最好的选择。例如,假设您编写了一个股票分析程序,并下载了一个文件,
其中包含 1000 种股票的价格。在这种情况下,让程序直接读取文件,而不是手工输入文件中所有的值,将
方便得多。同样,让程序将输出写入到文件将更为方便,这样可得到有关结果的永久性记录。
幸运的是,C++使得将读取键盘输入和在屏幕上显示输出(统称为控制台输入/输出)的技巧用于文件
输入/输出(文件 I/O)非常简单。第 17 章将更详细地讨论这些主题,这里只介绍简单的文本文件 I/O。

6.8.1 文本 I/O 和文本文件

这里再介绍一下文本 I/O 的概念。使用 cin 进行输入时,程序将输入视为一系列的字节,其中每个字
节都被解释为字符编码。不管目标数据类型是什么,输入一开始都是字符数据——文本数据。然后,cin
对象负责将文本转换为其他类型。为说明这是如何完成的,来看一些处理同一个输入行的代码。
假设有如下示例输入行:

来看一下使用不同数据类型的变量来存储时,cin 是如何处理该输入行的。首先,来看使用 char 数据
类型的情况:

输入行中的第一个字符被赋给 ch。在这里,第一个字符是数字 3,其字符编码(二进制)被存储在变
量 ch 中。输入和目标变量都是字符,因此不需要进行转换。注意,这里存储的数值 3,而是字符 3 的编码。
执行上述输入语句后,输入队列中的下一个字符为字符 8,下一个输入操作将对其进行处理。
接下来看看 int 类型:
在这种情况下,cin 将不断读取,直到遇到非数字字符。也就是说,它将读取 3 和 8,这样句点将成为
输入队列中的下一个字符。cin 通过计算发现,这两个字符对应数值 38,因此将 38 的二进制编码复制到变
量 n 中。

接下来看看 double 类型:

在这种情况下,cin 将不断读取,直到遇到第一个不属于浮点数的字符。也就是说,cin 读取 3、8、句
点和 5,使得空格成为输入队列中的下一个字符。cin 通过计算发现,这四个字符对应于数值 38.5,因此将
38.5 的二进制编码(浮点格式)复制到变量 x 中。
接下来看看 char 数组的情况:
在这种情况下,cin 将不断读取,直到遇到空白字符。也就是说,它读取 3、8、句点和 5,使得空格成
为输入队列中的下一个字符。然后,cin 将这 4 个字符的字符编码存储到数组 word 中,并在末尾加上一个
空字符。这里不需要进行任何转换。

最后,来看一下另一种使用 char 数组来存储输入的情况:
在这种情况下,cin 将不断读取,直到遇到换行符(示例输入行少于 50 个字符)。所有字符都将被存储
到数组 word 中,并在末尾加上一个空字符。换行符被丢弃,输入队列中的下一个字符是下一行中的第一
个字符。这里不需要进行任何转换。

对于输入,将执行相反的转换。即整数被转换为数字字符序列,浮点数被转换为数字字符和其他字符
组成的字符序列(如 284.53 或−1.58E+06)。字符数据不需要做任何转换。
这里的要点是,输入一开始为文本。因此,控制台输入的文件版本是文本文件,即每个字节都存储了
一个字符编码的文件。并非所有的文件都是文本文件,例如,数据库和电子表格以数值格式(即二进制整
数或浮点格式)来存储数值数据。另外,字处理文件中可能包含文本信息,但也可能包含用于描述格式、
字体、打印机等的非文本数据。
本章讨论的文件 I/O 相当于控制台 I/O,因此仅适用于文本文件。要创建文本文件,用于提供输入,可
使用文本编译器,如 DOS 中的 EDIT、Windows 中的“记事本”和 UNIX/Linux 系统中的 vi 或 emacs。

可以使用字处理程序来创建,但必须将文件保存为文本格式。IDE 中的源代码编辑器生成的也是文本文件,
事实上,源代码文件就属于文本文件。同样,可以使用文本编辑器来查看通过文本输出创建的文件。

6.8.2 写入到文本文件中

对于文件输入,C++使用类似于 cout 的东西。下面来复习一些有关将 cout 用于控制台输出的基本事实,
为文件输出做准备。

必须包含头文件 iostream。

头文件 iostream 定义了一个用处理输出的 ostream 类。

头文件 iostream 声明了一个名为 cout 的 ostream 变量(对象)。

必须指明名称空间 std;例如,为引用元素 cout 和 endl,必须使用编译指令 using 或前缀 std::。

可以结合使用 cout 和运算符<<来显示各种类型的数据。
文件输出与此极其相似。

必须包含头文件 fstream。

头文件 fstream 定义了一个用于处理输出的 ofstream 类。

需要声明一个或多个 ofstream 变量(对象),并以自己喜欢的方式对其进行命名,条件是遵守常用
的命名规则。

必须指明名称空间 std;例如,为引用元素 ofstream,必须使用编译指令 using 或前缀 std::。

需要将 ofstream 对象与文件关联起来。为此,方法之一是使用 open( )方法。

使用完文件后,应使用方法 close( )将其关闭。

可结合使用 ofstream 对象和运算符<<来输出各种类型的数据。
注意,虽然头文件 iostream 提供了一个预先定义好的名为 cout 的 ostream 对象,但您必须声明自己的
ofstream 对象,为其命名,并将其同文件关联起来。下面演示了如何声明这种对象:
下面演示了如何将这种对象与特定的文件关联起来:
注意,方法 open( )接受一个 C-风格字符串作为参数,这可以是一个字面字符串,也可以是存储在数组
192 C++ Primer Plus(第 6 版)中文版
中的字符串。
下面演示了如何使用这种对象:
重要的是,声明一个 ofstream 对象并将其同文件关联起来后,便可以像使用 cout 那样使用它。所有可
用于 cout 的操作和方法(如<<、endl 和 setf( ))都可用于 ofstream 对象(如前述示例中的 outFile 和 fout)。
总之,使用文件输出的主要步骤如下。
1.包含头文件 fstream。
2.创建一个 ofstream 对象。
3.将该 ofstream 对象同一个文件关联起来。
4.就像使用 cout 那样使用该 ofstream 对象。
程序清单 6.15 中的程序演示了这种方法。它要求用户输入信息,然后将信息显示到屏幕上,再将这些
信息写入到文件中。读者可以使用文本编辑器来查看该输出文件的内容。

该程序的最后一部分与 cout 部分相同,只是将 cout 替换为 outFile 而已。下面是该程序的运行情况:
屏幕输出是使用 cout 的结果。如果您查看该程序的可执行文件所在的目录,将看到一个名为 carinfo.txt
的新文件(根据编译器的配置,该文件也可能位于其他文件夹),其中包含使用 outFile 生成的输出。如果
使用文本编辑器打开该文件,将发现其内容如下:
正如读者看到的,outFile 将 cout 显示到屏幕上的内容写入到了文件 carinfo.txt 中。
程序说明
在程序清单 6.15 的程序中,声明一个 ofstream 对象后,便可以使用方法 open( )将该对象特定文件关联
起来:
程序使用完该文件后,应该将其关闭:
注意,方法 close( )不需要使用文件名作为参数,这是因为 outFile 已经同特定的文件关联起来。如果
您忘记关闭文件,程序正常终止时将自动关闭它。
outFile 可使用 cout 可使用的任何方法。它不但能够使用运算符<<,还可以使用各种格式化方法,如
setf( )和 precision( )。这些方法只影响调用它们的对象。例如,对于不同的对象,可以提供不同的值:
读者需要记住的重点是,创建好 ofstream 对象(如 outFile)后,便可以像使用 cout 那样使用它。
回到 open( )方法:
在这里,该程序运行之前,文件 carinfo.txt 并不存在。在这种情况下,方法 open( )将新建一个名为
carinfo.txt 的文件。如果在此运行该程序,文件 carinfo.txt 将存在,此时情况将如何呢?默认情况下,open( )
将首先截断该文件,即将其长度截短到零——丢其原有的内容,然后将新的输出加入到该文件中。第 17
章将介绍如何修改这种默认行为。
194 C++ Primer Plus(第 6 版)中文版
警告:打开已有的文件,以接受输出时,默认将它其长度截短为零,因此原来的内容将丢失。
打开文件用于接受输入时可能失败。例如,指定的文件可能已经存在,但禁止对其进行访问。因此细
心的程序员将检查打开文件的操作是否成功,这将在下一个例子中介绍。

6.8.3 读取文本文件

接下来介绍文本文件输入,它是基于控制台输入的。控制台输入涉及多个方面,下面首先总结这些
方面。

必须包含头文件 iostream。

头文件 iostream 定义了一个用处理输入的 istream 类。

头文件 iostream 声明了一个名为 cin 的 istream 变量(对象)。

必须指明名称空间 std;例如,为引用元素 cin,必须使用编译指令 using 或前缀 std::。

可以结合使用 cin 和运算符>>来读取各种类型的数据。

可以使用 cin 和 get( )方法来读取一个字符,使用 cin 和 getline( )来读取一行字符。

可以结合使用 cin 和 eof( )、fail( )方法来判断输入是否成功。

对象 cin 本身被用作测试条件时,如果最后一个读取操作成功,它将被转换为布尔值 true,否则
被转换为 false。
文件输出与此极其相似:

必须包含头文件 fstream。

头文件 fstream 定义了一个用于处理输入的 ifstream 类。

需要声明一个或多个 ifstream 变量(对象),并以自己喜欢的方式对其进行命名,条件是遵守常用
的命名规则。

必须指明名称空间 std;例如,为引用元素 ifstream,必须使用编译指令 using 或前缀 std::。

需要将 ifstream 对象与文件关联起来。为此,方法之一是使用 open( )方法。

使用完文件后,应使用 close( )方法将其关闭。

可结合使用 ifstream 对象和运算符>>来读取各种类型的数据。

可以使用 ifstream 对象和 get( )方法来读取一个字符,使用 ifstream 对象和 getline( )来读取一行字符。

可以结合使用 ifstream 和 eof( )、fail( )等方法来判断输入是否成功。

ifstream 对象本身被用作测试条件时,如果最后一个读取操作成功,它将被转换为布尔值 true,否
则被转换为 false。
注意,虽然头文件 iostream 提供了一个预先定义好的名为 cin 的 istream 对象,但您必须声明自己的
ifstream 对象,为其命名,并将其同文件关联起来。下面演示了如何声明这种对象:
下面演示了如何将这种对象与特定的文件关联起来:
注意,方法 open( )接受一个 C-风格字符串作为参数,这可以是一个字面字符串,也可以是存储在数组
中的字符串。
下面演示了如何使用这种对象:
第 6 章 分支语句和逻辑运算符 195
重要的是,声明一个 ifstream 对象并将其同文件关联起来后,便可以像使用 cin 那样使用它。所有可用
于 cin 的操作和方法都可用于 ifstream 对象(如前述示例中的 inFile 和 fin)。
如果试图打开一个不存在的文件用于输入,情况将如何呢?这种错误将导致后面使用 ifstream 对象进
行输入时失败。检查文件是否被成功打开的首先方法是使用方法 is_open( ),为此,可以使用类似于下面的
代码:
如果文件被成功地打开,方法 is_open( )将返回 true;因此如果文件没有被打开,表达式!inFile.isopen( )
将为 true。函数 exit( )的原型是在头文件 cstdlib 中定义的,在该头文件中,还定义了一个用于同操作系统
通信的参数值 EXIT_FAILURE。函数 exit( )终止程序。
方法 is_open( )是 C++中相对较新的内容。如果读者的编译器不支持它,可使用较老的方法 good( )来代
替。正如第 17 章将讨论的,方法 good( )在检查可能存在的问题方面,没有 is_open( )那么广泛。
程序清单 6.16 中的程序打开用户指定的文件,读取其中的数字,然后指出文件中包含多少个值以及它
们的和与平均值。正确地设计输入循环至关重要,详细请参阅后面的“程序说明”。注意,通过使用了 if
语句,该程序受益匪浅。

要运行程序清单 6.16 中的程序,首先必须创建一个包含数字的文本文件。为此,可以使用文本编辑器
(如用于编写源代码的文本编辑器)。假设该文件名为 scores.txt,包含的内容如下:
程序还必须能够找到这个文件。通常,除非在输入的文件名中包含路径,否则程序将在可执行文件所
属的文件夹中查找。
警告:Windows 文本文件的每行都以回车字符和换行符结尾;通常情况下,C++在读取文件时将这两
个字符转换为换行符,并在写入文件时执行相反的转换。有些文本编辑器(如 Metrowerks CodeWarrior IDE
编辑器),不会自动在最后一行末尾加上换行符。因此,如果读者使用的是这种编辑器,请在输入最后的文
本后按下回车键,然后再保存文件。
下面是该程序的运行情况:
程序说明

该程序没有使用硬编码文件名,而是将用户提供的文件名存储到字符数组 filename 中,然后将该数组
用作 open( )的参数:
正如本章前面讨论的,检查文件是否被成功打开至关重要。下面是一些可能出问题的地方:指定的文
件可能不存在;文件可能位于另一个目录(文件夹)中;访问可能被拒绝;用户可能输错了文件名或省略
了文件扩展名。很多初学者花了大量的时间检查文件读取循环的哪里出了问题后,最终却发现问题在于程
序没有打开文件。检查文件是否被成功打开可避免将这种将精力放在错误地方的情况发生。
读者需要特别注意的是文件读取循环的正确设计。读取文件时,有几点需要检查。首先,程序读取文
件时不应超过 EOF。如果最后一次读取数据时遇到 EOF,方法 eof( )将返回 true。其次,程序可能遇到类
型不匹配的情况。例如,程序清单 6.16 期望文件中只包含数字。如果最后一次读取操作中发生了类型不匹
配的情况,方法 fail( )将返回 true(如果遇到了 EOF,该方法也将返回 true)。最后,可能出现意外的问题,
如文件受损或硬件故障。如果最后一次读取文件时发生了这样的问题,方法 bad( )将返回 true。不要分别检
查这些情况,一种更简单的方法是使用 good( )方法,该方法在没有发生任何错误时返回 true:

然后,如果愿意,可以使用其他方法来确定循环终止的真正原因:

这些代码紧跟在循环的后面,用于判断循环为何终止。由于 eof( )只能判断是否到达 EOF,而 fail( )可
用于检查 EOF 和类型不匹配,因此上述代码首先判断是否到达 EOF。这样,如果执行到了 else if 测试,便
可排除 EOF,因此,如果 fail( )返回 true,便可断定导致循环终止的原因是类型不匹配。
方法 good( )指出最后一次读取输入的操作是否成功,这一点至关重要。这意味着应该在执行读取输入
的操作后,立刻应用这种测试。为此,一种标准方法是,在循环之前(首次执行循环测试前)放置一条输
入语句,并在循环的末尾(下次执行循环测试之前)放置另一条输入语句:
鉴于以下事实,可以对上述代码进行精简:表达式 inFile >> value 的结果为 inFile,而在需要一个 bool
值的情况下,inFile 的结果为 inFile.good( ),即 true 或 false。
因此,可以将两条输入语句用一条用作循环测试的输入语句代替。也就是说,可以将上述循环结构替
换为如下循环结构:
这种设计仍然遵循了在测试之前进行读取的规则,因为要计算表达式 inFile >> value 的值,程序必须
首先试图将一个数字读取到 value 中。
至此,读者对文件 I/O 有了初步的认识。

6.9 总结

使用引导程序选择不同操作的语句后,程序和编程将更有趣(这是否也能引起程序员们的兴趣,我没
有做过研究)。C++提供了 if 语句、if else 语句和 switch 语句来管理选项。if 语句使程序有条件地执行语句
或语句块,也就是说,如果满足特定的条件,程序将执行特定的语句或语句块。if else 语句程序选择执行
两个语句或语句块之一。可以在这条语句后再加上 if else,以提供一系列的选项。switch 语句引导程序执
行一系列选项之一。

C++还提供了帮助决策的运算符。第 5 章讨论了关系表达式,这种表达式对两个值进行比较。if 和 if else
语句通常使用关系表达式作为测试条件。通过使用逻辑运算符(&&、||和!),可以组合或修改关系表达式,
创建更细致的测试。条件运算符(?:)提供了一种选择两个值之一的简洁方式。

cctype 字符函数库提供了一组方便的、功能强大的工具,可用于分析字符输入。

对于文件 I/O 来说,循环和选择语句是很有用的工具;文件 I/O 与控制台 I/O 极其相似。声明 ifstream
和 ofstream 对象,并将它们同文件关联起来后,便可以像使用 cin 和 cout 那样使用这些对象。

使用循环和决策语句,便可以编写有趣的、智能的、功能强大的程序。不过我们刚开始涉足 C++的强
大功能,下一章将介绍函数。

相关文章:

C++ Primer Plus 第6版 读书笔记(6) 第 6 章 分支语句和逻辑运算符

第 6 章 分支语句和逻辑运算符 C是在 C 语言基础上开发的一种集面向对象编程、泛型编程和过程化编程于一体的编程语言&#xff0c;是C语言的超集。本书是根据2003年的ISO/ANSI C标准编写的&#xff0c;通过大量短小精悍的程序详细而全面地阐述了 C的基本概念和技术&#xff0c;…...

Java Class 加密工具 ClassFinal

Jar包加密工具 ClassFinal介绍环境依赖使用说明下载加密命令行示例maven插件方式无密码模式机器绑定启动加密后的jar启动参数给密码不加密码参数直接启动1. 密码文件获取2. 交互输入参考资料介绍 ClassFinal 是一款 java class 文件安全加密工具&#xff0c;支持直接加密jar包…...

【蓝桥杯集训·每日一题】AcWing 3555. 二叉树

文章目录一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解三、知识风暴最近公共祖先一、题目 1、原题链接 3555. 二叉树 2、题目描述 给定一个 n 个结点&#xff08;编号 1∼n&#xff09;构成的二叉树&#xff0c;其根结点为 1 号点。 进行 m…...

【JavaScript运行原理之V8引擎】V8引擎解析JavaScript代码原理

1. 编程语言的执行 高级语言最终都需要编译为低级语言才能被硬件执行&#xff0c;越高级的语言中间的转换时间越长&#xff0c;效率越低&#xff0c;越低级的语言执行素的越快&#xff0c;但是由于缺少高级语言便捷的语法特性所以很难编写代码。 2. 大杂烩JS 它是作者在1995…...

C++11:智能指针

文章目录1. 介绍1.1 动态内存与智能指针2. 使用2.1 创建2.2 使用3. 原理3.1 RAII3.2 像指针一样使用3.3 支持智能指针对象拷贝auto_ptrRAII4. 标准库中的智能指针4.1 unique_ptr模拟实现4.2 shared_ptr引用计数模拟实现定制删除器4.3 weak_ptrshared_ptr造成的循环引用问题与sh…...

ccc-pytorch-RNN(7)

文章目录一、RNN简介二、RNN关键结构三、RNN的训练方式四、时间序列预测五、梯度弥散和梯度爆炸问题一、RNN简介 RNN&#xff08;Recurrent Neural Network&#xff09;中文循环神经网络&#xff0c;用于处理序列数据。它与传统人工神经网络和卷积神经网络的输入和输出相互独立…...

docker安装(linux)

安装需要的软件包 yum install -y yum-utils 设置stable镜像仓库&#xff08;使用阿里云镜像&#xff09; yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 更新yum软件包索引 yum makecache fast 安装DOCKER 引擎 yum -y…...

【数据库概论】10.1 事务及其作用

事务是一系列的数据库操作&#xff0c;是数据库应用程序的基本逻辑单元 10.1 事务的基本概念 1.事务 事务是用户定义的一个数据库操作序列&#xff0c;是一个具有原子性的操作&#xff0c;不可再分&#xff0c;一个事务内的操作要么全做、要么都不做。一般来说&#xff0c;一…...

通讯录(C++实现)

系统需求通讯录是一个可以记录亲人、好友信息的工具。本章主要利用C来实现一个通讯录管理系统系统中需要实现的功能如下:添加联系人:向通讯录中添加新人&#xff0c;信息包括&#xff08;姓名、性别、年龄、联系电话、家庭住址&#xff09;最多记录1000人显示联系人:显示通讯录…...

轻松掌握C++的模板与类模板,将Tamplate广泛运用于我们的编程生活

C提高编程 本阶段主要针对C泛型编程和STL技术做详细讲解&#xff0c;探讨C更深层的使用 泛型编程:编写与类型无关的通用代码,是代码复用的一种手段。 模板 1.模板的概念 模板就是建立通用的模具&#xff0c;大大提高复用性 例如&#xff1a; 2.函数模板 C另一种编程思想称…...

pandas 数据预处理+数据概览 处理技巧整理(持续更新版)

这篇文章主要是整理下使用pandas的一些技巧&#xff0c;因为经常不用它&#xff0c;这些指令忘得真的很快。前段时间在数模美赛中已经栽过跟头了&#xff0c;不希望以后遇到相关问题的时候还去网上查&#xff08;主要是太杂了&#xff09;。可能读者跟我有一样的问题&#xff0…...

mmdetectionV2.x版本 训练自己的VOC数据集

mmdetection目录下创建data文件夹&#xff0c;路劲如图所示&#xff0c;不带yololabels 修改配置文件 mmdet/datasets/voc.py 配置图片格式 mmdet/datasets/xml_style.py 如果图片是jpg则改成jpg&#xff0c;是png格式就改成png&#xff0c;这里我不需要改&#xff0c;本…...

Shell - crontab 定时 git 拉取并执行 maven 打包

目录 一.引言 二.踩坑与实践 1.原始代码 2.mvn package 未执行与解决 [导入环境变量] 3.git pull 未执行与解决 [添加绝对路径] 三.总结 一.引言 git 任务部署在通道机&#xff0c;每天6点需要定时更新 jar 包并打包上线&#xff0c;所以需要在 linux 服务器上&#xff…...

408考研计算机之计算机组成与设计——知识点及其做题经验篇目3:指令的寻址方式

上篇文章我们讲到&#xff0c;指令的基本格式&#xff0c;一条指令通常包括操作码字段和地址码字段两部分&#xff1a; 操作码字段地址码字段并且我们还讲到根据操作数地址码的数目不同&#xff0c;可将指令分为零一二三四地址指令。感兴趣的小伙伴们可以看看小编的上一篇文章…...

前端包管理工具:npm,yarn、cnpm、npx、pnpm

包管理工具npm Node Package Manager&#xff0c;也就是Node包管理器&#xff1b; 但是目前已经不仅仅是Node包管理器了&#xff0c;在前端项目中我们也在使用它来管理依赖的包&#xff1b; 比如vue、vue-router、vuex、express、koa、react、react-dom、axios、babel、webpack…...

推荐系统 FM因式分解

reference&#xff1a;知乎 FM算法解析 LR算法没有二阶交叉 如果是id类特征&#xff0c;这里的x是0/1&#xff0c;raw的特征输入就是float&#xff0c;当然&#xff0c;在我的理解里&#xff0c;一般会把raw的特征进行分桶&#xff0c;还是映射到0/1特征&#xff0c;不然这个w…...

Maven基础入门

文章目录Maven简介Maven 工作模式1.仓库2.坐标Maven的基本使用1.常用命令2.生命周期依赖管理1.依赖配置2.依赖传递3.可选依赖4.排除依赖5.依赖范围IDEA配置MavenMaven简介 Apache Maven 是一个项目管理和构建工具&#xff0c;它基于项目对象模型(POM)的概念&#xff0c;通过一…...

传输层协议 TCP UDP

目录 协议前菜 端口号 ​编辑端口号范围划分 认识知名端口号(Well-Know Port Number) netstat pidof 传输层协议 UDP协议 UDP协议端格式 UDP的特点 面向数据报 UDP的缓冲区 UDP使用注意事项 基于UDP的应用层协议 TCP协议 TCP协议概念 TCP协议段格式 标志…...

一点就分享系列(实践篇6——上篇)【迟到补发】Yolo-High_level系列算法开源项目融入V8 旨在研究和兼容使用【持续更新】

一点就分享系列&#xff08;实践篇5-补更篇&#xff09;[迟到补发]—Yolo系列算法开源项目融入V8旨在研究和兼容使用[持续更新] 题外话 去年我一直复读机式强调High-level在工业界已经饱和的情况&#xff0c;目的是呼吁更多人看准自己&#xff0c;不管是数字孪生交叉领域&#…...

buu RSA 1 (Crypto 第一页)

题目描述&#xff1a; 两个文件&#xff0c;都用记事本打开&#xff0c;记住用记事本打开 pub.key: -----BEGIN PUBLIC KEY----- MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAMAzLFxkrkcYL2wch21CM2kQVFpY97 /AvKr1rzQczdAgMBAAE -----END PUBLIC KEY-----flag.enc: A柪YJ^ 柛x秥?y…...

Python 二分查找:bisect库的使用

✅作者简介&#xff1a;人工智能专业本科在读&#xff0c;喜欢计算机与编程&#xff0c;写博客记录自己的学习历程。 &#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&…...

性能优化之HBase性能调优

HBase是Hadoop生态系统中的一个组件&#xff0c;是一个分布式、面向列存储的内存型开源数据库&#xff0c;可以支持数百万列&#xff08;MySQL4张表在HBase中对应1个表&#xff0c;4个列&#xff09;、超过10亿行的数据存储。可用作&#xff1a;冷热数据分离HBase适合作为冷数据…...

图像金字塔,原理、实现及应用

什么是图像金字塔 图像金字塔是对图像的一种多尺度表达&#xff0c;将各个尺度的图像按照分辨率从小到大&#xff0c;依次从上到下排列&#xff0c;就会形成类似金字塔的结构&#xff0c;因此称为图像金字塔。 常见的图像金字塔有两类&#xff0c;一种是高斯金字塔&#xff0…...

08-Oracle游标管理(定义,打开、获取数据及关闭游标)

目标 1.确定何时需要显示游标2.声明、打开和关闭显示游标3.从显示游标中提取数据4.了解与游标有关的属性5.使用游标FOR循环检索游标中的数据6.在游标FOR循环的子查询中声明游标7.评估使用逻辑运算符结合在一起的布尔条件游标 1、在使用一个PL/SQL块来执行DML语句或只返回一行结…...

Python判断字符串是否包含特定子串的7种方法

目录1、使用 in 和 not in2、使用 find 方法3、使用 index 方法4、使用 count 方法5、通过魔法方法6、借助 operator7、使用正则匹配转自&#xff1a;https://cloud.tencent.com/developer/article/1699719我们经常会遇这样一个需求&#xff1a;判断字符串中是否包含某个关键词…...

aop实现接口访问频率限制

引言 项目开发中我们有时会用到一些第三方付费的接口&#xff0c;这些接口的每次调用都会产生一些费用&#xff0c;有时会有别有用心之人恶意调用我们的接口&#xff0c;造成经济损失&#xff1b;或者有时需要对一些执行时间比较长的的接口进行频率限制&#xff0c;这里我就简…...

Hive---窗口函数

Hive窗口函数 其他函数: Hive—Hive函数 文章目录Hive窗口函数开窗数据准备建表导入数据聚合函数window子句LAG(col,n,default_val) 往前第 n 行数据LEAD(col,n, default_val) 往后第 n 行数据ROW_NUMBER() 会根据顺序计算RANK() 排序相同时会重复&#xff0c;总数不会变DENSE…...

JavaSe第7次笔记

1. C语言里面&#xff0c;NULL是0地址。Java中null和0地址没关系。 2.数组可以做方法的返回值。 3.可以使用变量作为数组的个数开辟空间。 4.断言assert&#xff0c;需要设置。 5.排序&#xff1a;Arrays. sort(array); 6.查找&#xff1a; int index Arrays. binarySea…...

什么是 Service 以及描述下它的生命周期。Service 有哪些启动方法,有 什么区别,怎样停用 Service?

在 Service 的生命周期中,被回调的方法比 Activity 少一些,只有 onCreate, onStart, onDestroy, onBind 和 onUnbind。 通常有两种方式启动一个 Service,他们对 Service 生命周期的影响是不一样的。 1. 通过 startService Service 会经历 onCreate 到 onStart,然后处于运行…...

Redis部署

JAVA安装 mkdir /usr/local/javacd /usr/local/java/wget --no-check-certificate --no-cookies --header "Cookie: oraclelicenseaccept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u13…...

AT32F437制作Bootloader然后实现Http OTA升级

首先创建一个AT32F437的工程&#xff0c;然后发现调试工程配置这里的型号和创建工程选的型号不一致&#xff0c;手动更改一下&#xff0c;使用PW Link下载程序的话还要配置一下pyocd.exe的路径。 打开drv_clk.c文件的调试功能看下系统时钟频率。 项目使用的是AT32F437VMT7芯片&…...

Springboot项目启动初始化数据缓存

1.从Java EE5规范开始&#xff0c;Servlet中增加了两个影响Servlet生命周期的注解&#xff0c; PostConstruct和PreDestroy&#xff0c;这两个注解被用来修饰一个非静态的void&#xff08;&#xff09;方法&#xff0c;被PostConstruct修饰的方法会在服务器加载Servlet的时候运…...

深度学习必备知识——模型数据集Yolo与Voc格式文件相互转化

在深度学习中&#xff0c;第一步要做的往往就是处理数据集,尤其是学习百度飞桨PaddlePaddle的小伙伴&#xff0c;数据集经常要用Voc格式的&#xff0c;比如性能突出的ppyolo等模型。所以学会数据集转化的本领是十分必要的。这篇博客就带你一起进行Yolo与Voc格式的相互转化&…...

数据、数据资源及数据资产管理的区别

整理不易&#xff0c;转发请注明出处&#xff0c;请勿直接剽窃&#xff01; 点赞、关注、不迷路&#xff01; 摘要&#xff1a;数据、数据资源、数据资产 数据、数据资源及数据资产的区别 举例 CRM系统建设完成后会有很多数据&#xff0c;这些数据就是原始数据&#xff0c;业务…...

标度不变性(scale invariance)与无标度(scale-free)概念辨析

文章目录标度标度种类名义标度序级标度等距标度比率标度常用标度方法不足标度不变性标度不变&#xff08;Scale-invariant&#xff09;曲线和自相似性&#xff08;self-similarity&#xff09;射影几何分形随机过程中的标度不变性标度不变的 Tweedie distribution普适性&#x…...

WMS仓库管理系统解决方案,实现仓库管理一体化

仓库是企业的核心环节&#xff0c;若没有对库存的合理控制和送货&#xff0c;将会造成成本的上升&#xff0c;服务品质的难以得到保证&#xff0c;进而降低企业的竞争能力。WMS仓库管理系统包括基本信息&#xff0c;标签&#xff0c;入库&#xff0c;上架&#xff0c;领料&…...

css常见定位、居中方案_css定位居中

一、 定位分类 1、静态定位 position:static;&#xff08;默认&#xff0c;具备标准流条件&#xff09; 2、相对定位 position:relative; 通过 top 或者 bottom 来设置 Y 轴位置 通过 left 或者 right 来设置 X 轴位置 特点&#xff1a; 相对定位不会脱离文档流相对于自…...

【微信小程序】-- 自定义组件 -- 创建与引用 样式(三十二)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…...

ArangoDB——AQL编辑器

AQL 编辑器 ArangoDB 的查询语言称为 AQL。AQL与关系数据库管理系统 (RDBMS)区别在于其更像一种编程语言&#xff0c;更自然地适合无模式模型&#xff0c;并使查询语言非常强大&#xff0c;同时保持易于读写。数据建模概念 数据库是集合的集合。集合存储记录&#xff0c;称为文…...

Lesson 9.1 集成学习的三大关键领域、Bagging 方法的基本思想和 RandomForestRegressor 的实现

文章目录一、 集成学习的三大关键领域二、Bagging 方法的基本思想三、RandomForestRegressor 的实现在开始学习之前&#xff0c;先导入我们需要的库&#xff0c;并查看库的版本。 import numpy as np import pandas as pd import sklearn import matplotlib as mlp import sea…...

basic1.0链码部署(基于test-network 环境ubuntu20.04腾讯云)

解决了官方示例指令需要科学上网才能运行的问题&#xff08;通过手动下载二进制文件和拉取官方fabric-samples&#xff09;。具体的将bootstrap.sh脚本解读了一遍 具体可以参照我的博客 fabric中bootstrap.sh到底帮助我们干了什么&#xff1f;&#xff08;curl -sSL https://bi…...

Android---系统启动流程

目录 Android 系统启动流程 init 进程分析 init.rc 解析 Zygote 概叙 Zygote 触发过程 Zygote 启动过程 什么时Runtime&#xff1f; System Server 启动流程 Fork 函数 总结 面试题 Android 是 google 公司开发的一款基于 Linux 的开源操作系统。 Android 系统启动…...

【网络】http协议

&#x1f941;作者&#xff1a; 华丞臧. &#x1f4d5;​​​​专栏&#xff1a;【网络】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 推荐一款刷题网站 &#x1f449; LeetCode刷题网站 文章…...

Thread::interrupted() 什么意思? 如何中断线程?

1、答&#xff1a; Thread::interrupted() 是一个静态方法&#xff0c;用于判断当前线程是否被中断&#xff0c;并清除中断标志位。 具体来说&#xff0c;当一个线程被中断后&#xff0c;它的中断状态将被设置为 true。如果在接下来的某个时间点内调用了该线程的 interrupted…...

Oracle OCP 19c 考试(1Z0-083)中关于Oracle不完全恢复的考点(文末附录像)

欢迎试看博主的专著《MySQL 8.0运维与优化》 下面是Oracle 19c OCP考试&#xff08;1Z0-083&#xff09;中关于Oracle不完全恢复的题目: A database is configured in ARCHIVELOG mode A full RMAN backup exists but no control file backup to trace has been taken A media…...

一起来学习配置Combo接口吧!

Combo接口是一个光电复用的逻辑接口&#xff0c;一个Combo接口对应设备面板上一个GE电接口和一个GE光接口。电接口与其对应的光接口是光电复用关系&#xff0c;两者不能同时工作&#xff08;当激活其中一个接口时&#xff0c;另一个接口就自动处于禁用状态&#xff09;&#xf…...

C++模拟实现红黑树

目录 介绍----什么是红黑树 甲鱼的臀部----规定 分析思考 绘图解析代码实现 节点部分 插入部分分步解析 ●父亲在祖父的左&#xff0c;叔叔在祖父的右&#xff1a; ●父亲在祖父的右&#xff0c;叔叔在祖父的左&#xff1a; 测试部分 整体代码 介绍----什么是红黑树 红…...

HTTPS协议之SSL/TLS详解(下)

目录 前言&#xff1a; SSL/TLS详解 HTTP协议传输安全性分析 对称加密 非对称加密 证书 小结&#xff1a; 前言&#xff1a; 在网络世界中&#xff0c;存在着运营商劫持和一些黑客的攻击。如果明文传输数据是很危险的操作&#xff0c;因为我们不清楚中间传输过程中就被哪…...

OLE对象是什么?为什么要在CAD图形中插入OLE对象?

OLE对象是什么&#xff1f;OLE对象的意思是指对象连接与嵌入。那为什么要在CAD图形中插入OLE对象&#xff1f;一般情况下&#xff0c;在CAD图形中插入OLE对象&#xff0c;是为了将不同应用程序的数据合并到一个文档中。本节内容小编就来给大家分享一下在CAD图形中插入OLE对象的…...

【微信小程序】-- 自定义组件 -- 数据、方法和属性(三十三)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…...