设计智能程序的一个关键时使程序具有决策能力。C++提供了if和switch语句来进行决策。
6.1 if语句
if (test-condition)
statement
如果test-condition为true,则程序执行statement语句。若false,程序将跳过if语句。
6.1.1 if else语句
if (test-condition)
statement1
else
statement2
if语句让程序是否执行特定的语句或语句块,而if else语句则让程序决定执行两条语句或语句块中的那一条,这种语句对于选择其中一种操作很有用。
6.1.2 格式化if else语句
if (ch == '2')
{
zorro++;
cout << "Another";
}
else
{
dull++;
cout << "Not a ";
}
6.1.3 if else if else结构
if (ch == 'A')
{
a_grade++;
}
else if (ch == 'B')
{
b_grade++;
}
else
{
soso++
}
实际上,它只是一个if else被包含在另一个if else中。
6.2 逻辑表达式
C++提供了3种逻辑运算符,来组合和修改已有的表达式。分别使逻辑or(||)、逻辑and(&&)和逻辑not(!)。
6.2.1 逻辑or运算符: ||
||的优先级比关系运算符低。
C++规定,||运算符是个顺序点(sequence point)。也就是说,先修改左侧的值,在对右侧值进行判定。如果左侧是真,则C++不会去判断右侧的表达式。
i++ < 6 || i == j
分号和逗号也是顺序点。
6.2.2 逻辑and运算符: &&
&&运算符优先级比关系运算符低。 如果左侧为false,则整个逻辑表达式为错。C++则不会继续判断右侧表达式。
6.2.3 用&&设置取值范围
&&运算符还允许建立一系列的if else if else语句,其中每种选择都对应于一个特定的取值范围。
if (age > 17 && age < 35)
{
index = 0;
}
else if(age >= 35 && age < 50)
{
index = 1;
}
else
{
index = 2;
}
在使用取值范围测试时,应确保取值范围之间即没有缝隙,也没有重叠。
也不要用数学表达式表示取值范围:
if (17 < age < 35) // 错误
6.2.4 逻辑not运算符:!
!运算符将它后面的表达式的真值取反。
if (!(x > 5)) // if (x < 5) 更明确
!运算符对于返回true-false值或可以被解释为true-false值的函数很有用。
6.2.5 逻辑运算符细节
C++ 逻辑or和逻辑and优先级低于关系运算符。但是逻辑not的优先级高于所有关系运算符和算术运算符。因此,要对表达式求反,必须用括号将其括起
!(x > 5)
!x > 5 // 测试!x与5的关系
逻辑and优先级高于逻辑or。
age > 30 && age < 45 || weight > 300
// 被解释为 (age > 30 && age < 45) || weight > 300
虽然C++运算符的优先级规则常可能不使用括号便可以编写复杂比较语句,但最简单的方法还是用括号进行分组,而不管是否需要括号。
C++确保程序从左向右进行计算逻辑表达式。
6.4 ?:运算符
C++唯一一个需要3个操作数的运算符。
expression1 ? expression2 : expression3
如果expression1为true,则整个条件表达式的值为expression2的值;否则,整个表达式的值为expression3的值。
5 > 3 ? 10 : 12;
与if else相比,条件运算符更简介。
条件运算符生成一个表达式,因此是一个值,可以将其赋给变量或将其放到一个更大的表达式中。
6.5 switch语句
C++的switch语句能够更容易地从大型列表中进行选择。
switch (integer-expression)
{
case label1: statement(s)
case label2: statement(s)
case label3: statement(s)
...
default:statement(s)
}
C++的switch语句就像指路牌,告诉计算机接下来应执行那行代码。
integer-expression必须是一个结果为整数值的表达式。另外,每个标签都必须是整数常量表达式。最常见的标签是int或char常量(如1 或 ‘q’),也可以是枚举量。如果integer-expression不与任何标签匹配,则程序跳到标签为default哪一行。Default标签是可选的,如果被省略,而又没有匹配的标签,则程序将跳到switch后面的语句处执行。
C++中case只是行标签,而不是选项之间的界面。程序跳到switch特定代码行后,将依次执行之后的所有语句,除非有明确的其他指示。程序不会执行到下一个case处自动停止,要让程序执行完一组特定语句后停止,必须使用break语句。这将导致程序跳到switch后面的语句处执行。
6.5.1 将枚举量用作标签
switch语句将int值和枚举标签进行比较时,将枚举量提升为int。另外,在while循环测试条件中,也会将枚举量提升为int类型。
6.5.2 switch和if else
switch语句和if else语句都允许程序从选项中进行选择。相比之下,if else更通用。例如,它能处理取值范围。
switch语句的每个case标签都必须是一个单独的值。另外,这个值必须是整数(包括char),因此switch无法进行浮点测试。另外,case标签值还必须是常量。如果选项涉及取值范围、浮点测试或两个变量的比较,则应该使用if else语句。
如果所有选项都可以用整数常量来标识,则switch与if else都可以用。
如果switch与if else都可以用,则当选项不少于3个时,则应该使用switch语句。
6.6 break和continue语句
break和continue都使程序跳过部分代码。作用循环时, break语句使程序跳过循环的剩余部分,到达循环之外的下一条语句。continue语句跳过循环体中剩余的代码,并开始新一轮循环。
6.8 简单文件的输入/输出
C++使得将读取键盘输入和在屏幕输出的技巧用于文件输入/输出非常简单。
using namespace std;
ofstream outFile;
outFile.open("carinfo.txt"); //将覆盖原文件或创建新文件
outFile << "Market";
outFile.close();
ifstream inFile;
inFile.open("bowling.txt");
if(!inFile.is_open())
{
exit(EXIT_FAILURE);
}
文件输出 | 文件输入 |
必须包含头文件fstream; | 必须包含头文件fstream; |
头文件fstream定义了一个用于处理输出的ofstream类; | 头文件fstream定义了一个用于处理输出的ifstream类; |
需要声明一个或多个ofstream对象; | 需要声明一个或多个ifstream对象; |
必须指明名称空间std; | 必须指明名称空间std; |
需要将ofstream对象与文件关联起来,方法之一使用open()方法; | 需要将ifstream对象与文件关联起来,方法之一使用open()方法; |
使用完文件后,应使用方法close()将其关闭; | 使用完文件后,应使用方法close()将其关闭; |
可结合ofstream对象和运算符<<来输出各种类型的数据; | 可结合ofstream对象和运算符<<来输出各种类型的数据; get()方法来读取一个字符,getline()读取一行字符; 可结合ifstream和eof(),fail()等方法判断输入是否成功; ifstream对象本身被用作测试条件时,如果最后一个读取成功,它将被转换为布尔值true; |
6.9 总结
C++提供了if语句、if else语句和switch语句来管理选项。
if语句使程序有条件地执行语句或语句块。if else语句程序选择执行两个语句或语句块之一。可以在这条语句后面再加上if else,以提供一系列选择。switch语句引导程序执行一系列选项之一。
if和if else语句通常使用关系表达式作为测试条件,通过使用逻辑运算符(&&、||和!),可以组合或修改关系表达式,创建更细致地测试。
条件运算符(?:)提供了一种选择两个值之一地简介方式。
文件I/O与控制台I/O极其相似。声明ifstream与ofstream对象,并将它们同文件联系起来,便可以使用像cin和cout那样使用这些对象。
使用循环与决策语句,便可以编写有趣的、智能的、功能强大的程序。