2.21 结构化编程小结
建筑师设计大楼时,要采用前人的智慧,程序员设计程序时也要采用前人的智慧。我们的领域 比建筑领域要年轻,我们的集体智慧也比较少。前面曾介绍过,结构化编程产生的程序比非结构化编程的程序更容易理解,因此更容易测试、调试与修改,并在数学意义上更加正确。
图2.32总结了C++控制结构。图中的小圆表示每个结构的单入口点和单出口点。任意连接各个流程图符号可能造成非结构化编程。因此,编程专业人员选择用流程图符号组成有限的控制结构,通过用两种简单方法组合控制结构而建立结构化程序。
为了简单起见,我们只用单人/单出控制结构,每个控制结构只有一个入口和一个出口。顺序连接控制结构以形成简单的结构化程序,一个控制结构的出口连接下一个控制结构的人口,即控制结构只是在程序中一个接一个地放置,称为控制结构堆栈形式。形成结构化程序的规则还允许嵌套控制结构。
图2.33列出了正确形成结构化程序的规则。这个规则假设可以用流程图中的矩形框表示任何操作,包括输入/输出。
形成结构化程序的规则
1)从”最简单的流程图”开始(如图2.34所示)。
2)任何矩形框(操作)可以换成两个顺序矩形框(操作)。
3)任何矩形框(操作)可以换成任何控制结构(顺序、if/else、switch、while、do/while或for)。
4)可按任何顺序多次重复规则2和规则3。
图2.33 形成结构化程序的规则
图 2.34 最简单的流程图
利用图2.33所示的规则总是可以得到整洁的结构化流程图。例如,对最简单的流程图重复采用规则2即可得到包含许多顺序放置矩形框的流程图(如图2.35所示)。注意规则2产生控制结构堆栈,因此称为堆栈规则(stacking rule)。
图 2.35 最简单的流程图重复采用规则2
规则3称为嵌套规则(nesting rule)。对最简单的流程图重复采用规则3即可得到包含整齐嵌套控制结构的流程图。例如,图2.36中,首先将最简单的流程图中的矩形框换成双项选择结构(if/else)。然后再对双项选择结构中的两个矩形框采用规则3,将每个矩形框变成一个双项选择结构。每个双项选择结构周围的虚线框表示最初的简单流程图中被替换的矩形框。
规则4产生更大、更复杂且层次更多的嵌套结构。文中出现的流程图采用图2.33的规则,构成各种可能的结构化流程图.从而设置各种可能的结构化程序。
结构化方法的妙处在于我们只用两种简单方法组合七种简单的单入/单出块。图2.37显示了采用规则2的堆栈构件块和采用规则3的嵌套构件块。图中还显示了结构化流程图中不能出现的重叠构件块(因为要消除goto语句)。
如果遵照图2.33的规则,则不会生成图2.38所示的非结构化流程图。如果不能判断某个流程图是否结构化,可以逆向采用图2.33的规则,将这个流程图简化为最简单的流程图。如果能够将这个流程图简化为最简单的流程图,则原流程图是结构化流程图,否则不是结构化流程图。
结构化编程提倡简单性。Bohm和Jacopini已经证明,只需要三种控制形式:
- 顺序(sequence)
- 选择(selection)
- 重复(repetmon)
顺序结构很简单,选择可以用三种方法实现:
- if结构(单项选择)
- if/else结构(双项选择)
- switch结构(多项选择)
事实上很容易证明简单的if结构即可提供任何形式的选择,任何能用if/else结构和switch结构完成的工作,也可以组合简单if结构来实现(但程序可能不够流畅)。
重复可以用三种方法实现:
- while结构
- do/while结构
- for结构
很容易证明简单的while结构即可提供任何形式的重复,任何能用do/while和for结构完成的工作,也可以组合简单while结构来实现(但程序可能不够流畅)。
根据以上结果,C++程序中所需的任何控制形式均可以用下列形式表示:
- 顺序
- if结构(选择)
- while结构(重复)
这些控制结构只要用两种方式组合,即嵌套和堆栈。事实上,结构化编程提倡简单性。
本章介绍了如何将包含操作和判断的控制结构组合成程序。第3章将介绍另一个程序结构单元——函数(function),我们将介绍如何用函数组成更大的程序(函数也是由控制结构组成的)以及函数如何提高软件复用性。第6章将介绍C++的另一个程序结构单元——类(class),从类生成对象,并进行面向对象编程。下面通过用面向对象设计攻克的难题来继续介绍对象。