📄 02章 控制结构.txt
字号:
第2章 控制结构
教学目标
●了解基本问题的解决方法
●通过自上而下、逐步完善的过程开发算法
●用if、if/else和switch选择结构选择操作
●用while、do/while和for重复结构重复执行程序语句
●了解计数器控制重复与标记控制重复
●使用自增、自减、赋值和逻辑运算符
●使用break和continue此程序控制语句
2.1 简介
编写解决特定问题的程序之前,首先要彻底了解问题并认真计划解决问题的方法。编写程序时,还要了解可用的基本组件和采用实践证明的程序结构原则。本章将讨论结构化编程的理论和原理的所有问题。这里介绍的技术适用于大多数高级语言.包括C++。第6章在介绍C++面向对象编程时,将会介绍如何用第2章介绍的控制结构帮助建立和操作对象。
2.2 算法
任何计算问题都可以通过按特定顺序执行一系列操作而完成。解决问题的过程(procedure)称为算法(algorithm),包括:
1.执行的操作(action)
2.执行操作的顺序(order)
下例演示正确指定执行操作的顺序是多么重要:
考虑每个人早晨起床到上班的“朝阳算法”:(1)起床,(2)脱睡衣,(3)洗澡,(4)穿衣,(5)吃早饭,(6)搭车上班。
总裁可以按这个顺序,从容不迫地来到办公室。假设把顺序稍作调换:(1)起床,(2)脱睡衣,(3)穿衣,(4)洗澡,(5)吃早饭.(6)搭车上班。
如果这样,总裁就得带着肥皂水来上班。指定计算机程序执行语句的顺序称为程序控制(program control),本章介绍C++程序的控制功能。
2.3 伪代码
伪代码(pseudocode)是人为的非正式语言,帮助程序员开发算法。这里介绍的伪代码在开发的算法转换为结构化C++程序时特别有用。伪代码类似于日常英语,方便而且容易掌握,但不是实际计算机编程语言。伪代码程序并不在计算机上实际执行,而是帮助程序员先“构思”程序.再用C++之类的实际计算机编程语言编写。本章介绍几个如何在开发结构化C++程序时有效利用伪代码的例子。
我们介绍的伪代码完全由字符构成,程序员可以用一个编辑器程序方便地输入伪代码程序,计算机可以在需要时显示伪代码程序。认真构思的伪代码程序可以方便地变为对应的C++程序。很多情况下,只要将伪代码语句转换成对应的C++语句即可。
伪代码只包含执行语句,将伪代码程序变为对应的C++程序时,这些语句可以运行。声明语句不是执行语句。例如,下列声明:
int i;
只是告诉编译器,变量i的类型是整型,指示编译器在内存中为这个变量保留内存空间。但这个声明并在执行程序时不做任何操作(如输入、输出或计算)。有些程序员在伪代码程序开头列出变量及其简要说明。
2.4 控制结构
通常,程序中的语句按编写的顺序一条一条地执行,称为顺序执行(sequential execution)。程序员可以用稍后要介绍的不同C++语句指定下一个执行的语句不是紧邻其后的语句,这种技术称为控制转移(transfer of control)。
20世纪60年代,人们发现,软件开发小组遇到的许多困难都是由于控制转移造成的。goto语句使程序员可以在程序中任意指定控制转移目标,因此人们提出结构化编程就是为了清除goto语句。
Bohm和JMoP5n1的研究表明,不用goto语句也能编写程序。困难在于程序员要养成不用goto语句的习惯。直到20世纪70年代,程序员才开始认真考虑结构化编程,结果使软件开发小组的开发时间缩短、系统能够及时交付运行并在颅算之内完成软件项目。这些成功的关键是.结构化编程更清晰、更易调试与修改并且不容易出错。
BohM和J“jecopini的研究表明,所有程序都可以只用三种控制结构(control structure)即顺序结构(sequence structure)、选择结构(selection structure)和重复结构(repetition structure)。顺序结构是C++内置的,除非另外指定,计算机总是按编写的顺序一条一条地执行。图2.1的流程图(flowchart)演示了典型的顺序结构.按顺序进行两次计算。
流程图是算法或部分算法的图形表示。流程图用一些专用符号绘制,如长方形、菱形、椭圆和小圆,这些符号用箭头连接,称为流程。
和伪代码一样,流程图也用于开发和表示算法,但伪代码更受欢迎。流程图能清楚地表示控制结构如何操作.本书用流程图表示控制结构如何操作。
考虑图2.1所示的流程图。我们用矩形框(或称为执行框)表示各种操作,包括计算、输入和输出操作。图中的流程表示进行操作的顺序,首先将grade加进total,然后将counter加1。C++允许顺序结构中有多个操作,稍后可以看出,可以放一个操作的地方,也就可以放几个顺序操作。
绘制表示完整算法的流程图时,椭圆框加上其中的“Begin”(开始)字样表示流程图开始,椭圆框加上其中的“End”(结束)字样表示流程图结束。只画部分算法时(如图2.1),省略椭圆框,只用小圆框,也称接头框。
最重要的流程图符号是菱形框,也称为判断框,表示要进行判断。下一节将介绍菱形框。
C++提供三种选择结构,本章将介绍这三种选择结构。if选择结构在条件为true时执行一个操作,在条件为false时跳过这个操作。if/else选择结构在条件为true时执行一个操作,在条件为false时执行另一个操作。swutch选择结构根据表达式取值不同而选择不同操作。
if选择结构称为单项选择结构(single—selection,structure),选择或忽略一个操作。if/else选择结构称为双项选择结构(double-selection structure),在两个不同操作中选择。switch选择结构称为多项选择结构(multiple-selection structure),在多个不同操作中选择。
C++提供三种重复结构while、do/while和for。if、else、switch、while、do和for等都是C++关键字(keyword)。这些关键字是该语言保留的,用于实现如C++控制结构等不同特性。关键字不能作为变量名等一些标识符。图2.2显示了完整的C++关键字列表。
-----------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------
常见编程错误 2.1
用关键字作为标识符属于语法错误。
C++只有七种控制结构:顺序结构、三种选择结构和三种重复结构。每个C++程序都是根据程序所需的算法组合这七种控制结构。从图2.1中的顺序结构可以看出,每个控制结构的流程图使用两个小圆框,一个在控制结构入口点,一个在控制结构出口点。这种单入/单出控制结构(single-entry/single-exit control structure)使程序容易建立,只要将一个控制结构的出口与另一个控制结构的入口连接,即可组成程序。这点很像小孩子堆积木,因此称为控制结构堆栈(control-structure stacking),还有另一种控制结构连接方法,称为控制结构嵌套(control-structure nesing)。
软件工程视点 2.1
任何C++程序可以用这七种控制结构(顺序、if、if/else、switch、while、do/while和for并用两种方式(控制结构堆栈和控制结构嵌套)组合而成。
2.5 if选择结构
选择结构在不同操作之间选择。例如,假设考试成绩60分算及格,则下列伪代码:
if student's grade is greater than or equal to 60
print "Passed"
确定“学生成绩大于或等于60分”是true或false,如果是true,则该生及格,打印“Passed”字样,并顺序“执行”下一个伪代码语句(记住,伪代码不是真正的编程语言)。如果条件为false,则忽略打印语句,并顺序“执行”下一个伪代码语句。注意这个选择结构第二行的缩排,这种缩排是可选的,但值得提倡,因为它能体现结构化程序的内部结构。将伪代码变成C++代码时,C++编译器忽略空格、制表符、换行符等用于缩排和垂直分隔的空白字符。
编程技巧 2.1
在整个程序中坚持用合理缩排规则能大大提高程序可读性。建议用固定制表长度即1/4英寸或三个空格的缩排量。
上述伪代码的if语句可以写成如下C++语句:
if(grade>=60)
cout<<"Passed";
cout<<"Passed";
注意C++代码与伪代码密切对应,这是伪代码的一个属性,使得其成为有用的程序开发工具。
编程技巧 2.2
伪代码常用于程存设计期间“构思”程序,然后再将伪代码程序转换为C++程序。
图2.3的流程图演示了单项选择if结构。这个流程图包含流程图中最重要的菱形框、也称判断框,表示要进行判断。判断框包含一个表达式(如条件),可取true或false值。判断框产生两条流程,一条指向表达式为true时的走向,一条指向表达式为false时的走向。第1章曾介绍过,可以根据包含关系或相等运算待的条件作出判断。实际上,可以针对任何表达式作出判断,如果表达式求值为0,则当作false,如果表达式求值非0,则当作true。C++草案标准提供bool数据类型,表示true和false。关键字true和false表示bool数据类型的值。
注意,if结构也是单入/单出结构。稍后将会介绍,其余控制结构的流程图(除了小圆框和流程之外)也只能包含表示所要操作的矩形框和表示所要判断的菱形框。这是我们强调的操作/判断编程模型(action/decision model of progamming)。
可以想像有七个框,各包含七种控制结构中的一种控制结构,这些控制结构是空的,矩形框和菱形框中什么也没有。程序员的任务就是根据算法需要用堆栈和嵌套两种方法组合这几种控制结构,然后在这些框中填入算法所要的操作和判断,从而生成程序。下面介绍编写操作和判断的各种方式。
2.6 if/else选择结构
if选择结构只在条件为true时采取操作,条件为false时则忽略这个操作。利用if/else选择结构则可以在条件为true时和条件为false时采取不同操作。例如,下列伪代码:
if student's grade is greater than or equal to 60
print "Passed"
else
print "Failed"
在学生成绩大于或等于60时打印“Passed”,否则打印"Failed"。打印之后,都“执行”下一条伪代码语句。注意else的语句体也缩排。
编程技巧 2.3
if/eIse选择结构的两个语句体都缩排。
选择的缩徘规则应当在整个程序中认真贯彻执行。不按统一缩排规则编写的程序很难阅读。
编程技巧 2.4
如果有多层缩排,则每一层应缩排相同的空间量。
上述伪代码if/else结构可以写成如下的C++代码:
if(grade>=60)
cout<<"Passed";
else
cout<<"Failed";
图2.4的流程图很好地演示了if/else结构的控制流程。注意,这个流程图(除了小圆框和流程之外)也只能包含表示所要操作的矩形框和表示所要判断的菱形框。这里我们继续强调操作/判断模型计算,假设框中包含建立C++程序所需的空白双项选择结构。程序员的任务就是根据算法需要用堆栈和嵌套两种方法组合各种控制结构,然后在这些框中填人算法所要的操作和判断,从而生成程序。
C++提供条件运算符(?:),与if/else结构密切相关。条件运算符是C++中惟一的三元运算符(thrnary operator),即取三个操作数的运算符。操作数和条件运算符一起形成条件表达式(conditional expression)。第一个操作数是条件,第二个操作数是条件为true时整个条件表达式的值.第三个操作数是条件为false时整个条件表达式的值。例如,下列输出语句:
cout<<(grade>=60? "Passed":"Failed");
包含的条件表达式在grade=60取值为true时,求值为字符串“Passed”;在grade>=60取值为false时,求值为字符串"Failed"。这样,带条件表达式的语句实际上与上述if/else语句相同。可以看出,条件运算符的优先级较低,因此上述表达式中的话号是必需的。
条件表达式酌值也可以是要执行的操作。例如.下列条件表达式:
grade >=60? cout<<"Passed": cout<<"Failed";
表示如果grade大于或等于60,则执行cout<<"Passed",否则执行cout<<"Failed"。这与前面的if/else结构也是相似的。条件运算符可以在一些无法使用if/else语句的情况中使用。
嵌套if/else结构(nested if/else structure)测试多个选择,将一个if/else选择放在另一个if/else选择中。例如,下列伪代码语句在考试成绩大于或等于90分时打印A.在80到89分之间时打印B,在70到79分之间时打印C,在60到69分之间时打印D,否则打印F。
if studen's grade is greater than or equal to 90
print "A"
else
If student's grade is greater than or equal to 80
print "B"
else
If student's grade is greater than or equal to 70
print "C"
else
If student's grade is greater than or equal to 60
print "D"
else
print "F"
这个伪代码对应下列C++代码:
if(grade>=90)
cout<<"A";
else
if(grade>=80)
cout<<"B";
else
if(grade>=70)
cout<<"C";
else
if(grade>=60)
cout<<"D";
else
cout<<"F";
如果考试成绩大于或等于90分,则前4个条件都为true,但只执行第一个测试之后的cout语句。执行这个cout语句之后,跳过外层if/else语句的else部分。许多C++程序员喜欢将上述if结构写成:
if(grade>=90)
cout<<"A";
else if(grade>=80)
cout<<"B";
else if(grade>=70)
cout<<"C";
else if(grade>=60)
cout<<"D";
else
cout<<"F";
两者形式是等价的。后者更常用,可以避免深层缩排便代码移到右端。深层缩排会使一行的空间太小,不长的行也要断行,从而影响可读性。
编程提示2.1
嵌套if/else结构比一系列单项选择if结构运行速度快得多,因为它能在满足其中一个条件之后即退出。
性能提示2.2
在嵌套if/else结构中,测试条件中true可能性较大的应放在嵌套if/else结构开头.从而使嵌套if/else结构运行更快,比测试不常发生的情况能更早退出。
if选择结构体中只能有一条语句。要在if选择结构体中包括多条语句,就要把这些语句放在花括号({ })中。放在花括号中的一组语句称为复合语句(compund statement)。
软件工程视点2.2
复合语句可以放在程序中出现单句语句的任何地方。
下例在if/else结构的else部分包括复合语句:
if(grade>=60)
cout<<"Passed.\n";
else{
cout<<"Failed.\n";
cout<<"You must take this course again.\n";
}
如果grade小于60,则程序执行else程序体中的两条语句并打印:
Failed.
You must take this course again.
注意else从句中的两条语句放在花括号中。这些花括号很重要,如果没有这些花括号,则下列语句:
cout<<"You must take this cours again.\n";
在if语句else部分之外,不管成绩是否小于60都执行。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -