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

C++ Primer Plus 学习笔记

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

if 语句

if (test-condition)
    statement

整个if语句被视为一条语句。

if else 语句
if (test-condition)
    statement1
else
    statement2

整个if else结构被视为一条语句。

if else if else 语句
if (test-condition)
    statement1
else
    if (test-condition)
        statement2
    else
        statement3

if (test-condition)
    statement1
else if (test-condition)
    statement2
else
    statement3
条件运算符和错误防范

许多程序员将更直观的表达式variable == value反转为value == varialbe,以此来捕获将相等运算符误写为赋值运算符的错误。

逻辑表达式

C++ 提供了 3 种逻辑运算符,分别是逻辑 OR||、逻辑 AND&&、逻辑 NOT!

逻辑 OR 运算符:||
expr1 || expr2 的值
expr1 == trueexpt1 == false
expr2 == truetruetrue
expr2 == falsetruefalse

||的优先级比关系运算符低。
C++ 规定,||运算符是个顺序点。

逻辑 AND 运算符:&&
expr1 && expr2 的值
expr1 == trueexpt1 == false
expr2 == truetruefalse
expr2 == falsefalsefalse

&&的优先级比关系运算符低。
C++ 规定,&&运算符也是个顺序点。

逻辑 NOT 运算符:!

!运算符将它后面的表达式的值取反。对于返回true-false值或可以解释为true-false值的函数来说很有用。

逻辑运算符细节

C++ 逻辑 OR 和逻辑 AND 运算符的优先级都低于关系运算符。
逻辑 NOT 运算符的优先级高于所有的关系运算符和算术运算符。
逻辑 AND 运算符的优先级高于逻辑 OR 运算符。
虽然 C++ 运算符的优先级规则常可能不使用括号便可以编写复合比较的语句,但最简单的方法还是用括号将测试进行分组,而不管是否需要括号。这样代码容易阅读,避免读者查看不常使用的优先级规则,并减少由于没有准确记住所使的规则而出错的可能性。
C++ 确保程序从左向右进行计算逻辑表达式,并在知道答案后立刻停止。

其他表示方式

标识符andornot都是 C++ 保留字,这意味着不能将它们用作变量名等。它们不是关键字,因为它们都是已有语言特性的另一种表示方式。另外,它们并不是 C 语言中的保留字,但语言程序可以将它们用作运算符,只要在程序中包含了头文件iso646.h。C++ 不要求使用头文件。

运算符另一种表示方式
&&and
||or
!not

字符函数库 cctype

C++ 从 C 语言继承了一个字符函数库,原型在关文件cctype(老式的风格中为ctype.h)中定义。(这些函数返回的类型为int,而不是bool,但通常类型转换可视为是bool类型。)

cctype 中的字符函数
函数名称返回值
isalnum()如果参数是字母数字,即字母或数字,该函数返回 true
isalpha()如果参数是字母,该函数返回 true
iscntrl()如果参数是控制字符,该函数返回 true
isdigit()如果参数是数字(0~9),该函数返回 true
isgraph()如果参数是除空格之外的打印字符,该函数返回 true
islower()如果参数是小写字母,该函数返回 tnue
isprint()如果参数是打印字符(包括空格),该函数返回 true
ispunct()如果参数是标点符号:该函数返回truc
isspace()如果参数是标准空白字符:如空格、进纸、换行符、回车、水平制表符或者垂直制表符,该函数返回 true
isupper()如果参数是大写字母,该函数返问 truc
isxdigit()如果参数是十六进制数字,即 0~9、a~f 或 A~F,该函数返回 true
tolower()如果参数是大写字符,则返回其小写,否则返回该参数
toupper()如果参数是小写字符,则返回其大写,否则返回该参数

?:运算符

C++ 有一个常被用来代替if else语句的运算符,被称为条件运算符?:,它是 C++ 中唯一一个需要 3 个操作数的运算符。该运算符的通用格式如下:

expression1 ? expression2 : expression3

如果expression1ture,则整个表达式的值为expression2的值,否则,为expression3的值。

int c = a > b ? a : b;
\\与下面语句等效
int c;
if (a > b)
    c = a;
else
    c = b;

if else序列相比,条件运算符更简洁。两种方法之间的区别是,条件运算符生成一个表达式,因此是一个值,可以将其赋给变量或将其放到一个更大的表达式中。其中一个技巧(它完成一个应被谴责的任务——隐藏代码)是将条件表达式嵌套在另一个条件表达式中:

const char x[2][20] = {"Jason", "at your service\n"};
const char * y = "Quillstone";
for (int i = 0; i < 3; i++)
    cout << ((i < 2) ? !i ? x[i] : y : x[1]);
\\print
Jason Quillstone at your service.

从可读性来说,条件运算符最适合于简单关系和简单表达式的值。

switch 语句

C++ 的switch语句能够更容易从大型列表中进行选择。通用格式如下:

switch (integer-expression)
{
    case label1 : statement(s)
    case label2 : statement(s)
    ...
    default     : statement(s)
}

integer-expression必须是一个结果为整数值的表达式,每个标签都必须是整数常量表达式,最常见的标签是intchar常量(如1q),也可以是枚举量。如果integer-expression不与任何标签匹配,则程序跳到default那一行,default标签是可选的,如果被省略,而又没有匹配的标签,则程序将跳到switch后面的语句处。
C++ 中的case标签只是行标,而不是选项之间的界线。程序跳到特定行后,将依次执行这后的所有代码,不会执行到一下case处自动停止,因此,必须使用break语句让程序跳到switch后面的语句处执行。这样做的好处是可以使用多个标签。

将枚举量用作标签

switch语句将int值与枚举量标签进行比较时,将枚举量提升为int。另外,在while循环测试条件中,也会将枚举量提升为int类型。

switch 和 if else

如果选项涉及聚会范围、浮点测试或两个变量的比较,则应使用if else语句。
如果既可以使用if else if语句,也可以使用switch语句,则当选项不少于 3 个时,应使用switch语句,因为如果选项超过两个,应代码长度和执行速度而言,switch语句的效率更高。

break 和 continue 语句

break语句使用程序跳到switch或循环后面的语句处执行,continue语句让程序跳过循环体中余下的代码,并开始新一轮循环。
和 C 语言一样,C++ 也有goto语句,可以使用程序跳到指定标签处,但在大多数情况下(有人认为在任何情况下),使用goto语句不好,而应使用结构化控制语句(如if else``switch``continue等)来控制程序的流程。

读取数字的循环

假设要编写一个将一系列数字读入到数组中的程序,并允许用户在数组填满之前结束输入。一种方法
是利用cin,如果用户输入一个单词,一而不是一个数字,将发生4种情况:

  • 数组值不变;
  • 不匹配的输入将被留在输入队列中;
  • cin对象中的一个错误标记被设置;
  • cin方法的调用将返回false(如果被转换为bool类型)。

方法返回false意味着可以用非数字输入来结束读取数字的循环。非数字输入设置错误标记意味着必须重置该标记,程序才能继续读取输入。clear()方法重置错误输入标记,同时也重置文件尾(EOF)条件。输入错误和 EOF 都将导致cin返回false
cin >> n实际上是一个cin方法函数调用,该函数返回cin。如果cin位于测试条件中,则将被转换成bool类型,如果输入成功则转换后的值为true,否则为false

如果需要提示错误后需要继续输入数字,应采取 3 个步骤:

  • 重置cin以接受新的输入;
  • 删除错误的输入;
  • 提示重新输入。

简单的文件输入/输出

C++ 使得将读取键盘输入和屏幕输出(统称为控制台输入/输出)的技巧用于文件输入/输出(文件 I/O)。

文件 I/O 和文本文件

使用cin进行输入时,程序将输入视为一系列的字节,其中每个字节都被解释为字符编码。不管目标数据类型是什么,输入一开始都是字符数据——文本数据。然后cin对象负责将文本转换为其他类型。
假设有如下示例输入行:

38.5 19.2

使用不同数据类型的变量来存储时,cin是如何处理该输入行的。

char ch;
cin >> ch;

输入行中的第一个字符被赋给ch。在这里,第一个字符是数字3,其字符编码(二进制)被存储在变
ch中。输入和目标变量都是字符,因此不需要进行转换。执行上述输入语句后,输入队列中的下一个字符为字符8,下一个输入操作将对其进行处理。

int n;
cin >n;

在这种情况下,cin将不断读取,直到遇到非数字字符。也就是说,它将读取38,这样句点将成为输入队列中的下一个字符。cin通过计算发现,这两个字符对应数值38,因此将38的二进制编码复制到变量n中。

double x;
cin >> x;

在这种情况下,cin将不断读取,直到遇到第一个不属于浮点数的字符。也就是说,cin读取38.5,使得空格成为输入队列中的下一个字符。cin通过计算发现,这四个字符对应于数值38.5,因此将38.5的二进制编码(浮点格式)复制到变量x中。

char word[50];
cin >> word;

在这种情况下,cin将不断读取,直到遇到空白字符。也就是说,它读取38.5,使得空格成为输入队列中的下一个字符。然后,cin将这 4 个字符的字符编码存储到数组word中,并在末尾加上一个空字符。这里不需要进行任何转换。

char word[50];
cin.getline(word, 50);

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

对于输出,将执行相反的转换。即整数被转换为数字字符序列,浮点数被转换为数字字符和其他字符
组成的字符序列非(如284.53-1.58E+06)。字符数据不需要做任何转换。

这里的要点是,输入一开始为文本。因此,控制台输入的文件版本是文本文件,即每个字节都存储了
一个字符编码的文件。

写入到文本文件

对于文件输出,C++ 使用类似cout的东西。

  • 必须包含头文件fstream
  • 头文件fstream定义了一个用于处理输出的ofstream类;
  • 需要声明一个或多个ofstream变量(对象),并命名;
  • 必须指明名称空间std;
  • 需将ofstream对象与文件关联起来,方法之一是使用open()方法(新建一个文件);
  • 使用完文件,要使用close()方法将其关闭;
  • 可结合使用ofstream对象和运算符<<来输出各种类型的数据。

注意:头文件iostream提供了一个预先定义好的名为coutostream对象,但必须自己声明自己的ofstream对象,为其命名,并将共与文件关联起来。
注意:方法open()接受一个C-风格字符串作为变量,这可以是一个字面字符串,也可以是存储在数组中的字符串。
重要的是,声明一个ofstream对象并将其同文件关联起来后,便可以像使用cout那样使用它。所有可用于cout的操作和方法(如<<endlsetf())都可用于ofstream对象。
总之,使用文件输出的主要步骤如下:

  • 包含头文件fstream
  • 创建ofstream对象;
  • ofstream对象与一个文件关联;
  • 像使用cout那样使用ofstream对象。
读取文件文件

读取文件与控制台输入类似。

  • 必须包含头文件fstream
  • 头文件fstream定义了一个用于处理输入的ifstream类;
  • 需要声明一个或多个ifstream变量(对象),并命名;
  • 必须指明名称空间std;
  • 需将ofstream对象与文件关联起来,方法之一是使用open()方法;
  • 使用完文件,要使用close()方法将其关闭;
  • 可结合使用ifstream对象和运算符>>来读取各种类型的数据。
  • 可结合使用ifstream对象和get()方法来读取一个字符,getline()方法来读取一行字符。
  • 可结合使用ifstream对象和eof()fail()等方法判断输入是否成功。

注意:头文件iostream提供了一个预先定义好的名为cinistream对象,但必须自己声明自己的ifstream对象,为其命名,并将共与文件关联起来。
重要的是,声明一个ifstream对象并将其同文件关联起来后,便可以像使用cin那样使用它。所有可用于cin的操作和方法都可用于ifstream对象。

检查文件是否被成功打开的首先方法是使用方法is_open(),如果文件被成功打开,方法is_open()将返回true
函数exit(EXIT_FAILURE)的原型和同操作系统通信的参数在头文件cstdlib中定义。
方法is_open()是 C++ 中相对较新的内容,如果编译器不支持,可使用较老的方法good()来代替,该方法在没有任何错误的时候返回true

第 6 章总结

C++ 提供了if语句、if else语句和switch语句来管理选项。if语句使程序有条件地执行语句或语句块,也就是说,如果满足特定的条件,程序将执行特定的语句或语句块。if else语句程序选择执行两个语句或语句块之一。可以在这条语句后再加上if else,以提供一系列的选项。switch语句引导程序执行一系列选项之一。
C++ 还提供了帮助决策的运算符。ifif else语句通常使用关系表达式作为测试条件。通过使用逻辑运算符(&&||!),可以组合或修改关系表达式,创建更细致的测试。条件运算符(?:)提供了一种选择两个值之一的简洁方式。
cctype字符函数库提供了一组方便的、功能强大的工具,可用于分析字符输入。
对于文件 I/O 来说,循环和选择语句是很有用的工具;文件 I/O 与控制台 I/O 极其相似。声明ifstreamofstream对象,并将它们同文件关联起来后,便可以像使用cincout那样使用这些对象。
使用循环和决策语句,便可以编写有趣的、智能的、功能强大的程序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值