第 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++的强
大功能,下一章将介绍函数。