结构程序设计的概念最早由E.W.Dijkstra提出。1965年他在一次会议上指出:“可以从高级语言中取消GO TO语句”,“程序的质量与程序中所包含的GO TO语句的数量成反比”。1966年Bohm和Jacopini证明了,只用3种控制结构就能实现任何单入口单出口的程序。这3种基本的控制结构是“顺序”、“选择”和“循环”,它们的流程图分为图5.1(a),5.1(b)和5.1(c)。
图5.1 3种基本的控制结构
实际上用顺序结构和循环结构(又称DO_WHILE结构)完全可以实现选择结构又称(IF_THEN_ELSE结构),因此,理论上最基本的控制结构只有两种。
Bohm和Jacopini的证明给结构程序设计技术奠定了理论基础。
1968年Dijkstra再次建议从一切高级语言中取消GO TO语句,只使用3种基本控制结构写程序。他的建议引起了激烈争论,经过讨论人们认识到,不是简单地去掉GO TO语句的问题,而是要创立一种新的程序设计思想、方法和风格,以显著地提高软件生产率和降低软件维护代价。
1971年IBM公司在纽约时报信息库管理系统的设计中成功地使用了结构程序设计技术,随后在美国宇航局实验室飞行模拟系统的设计中,结构程序设计技术再次获得圆满成功。这两个系统都相当庞大,前者包含83000行高级语言源程序,后者包含40万行源程序,而且在设计过程中用户需求又曾有过很多改变,然而两个系统的开发工具都按时并且高质量地完成了。这表明,软件生产率比以前提高了一倍,结构程序设计技术成功地接受了实践的检验。
1972年IBM公司的Mills进一步提出,程序应该只有一个入口和一个出口,从而补充了结构程序设计的规则。
那么,什么是结构程序设计呢?结构程序设计的经典定义如下所述:“如果一个程序的代码块仅仅通过顺序、选择和循环这3种基本控制结构进行连接,并且每个代码块只有一个入口和一个出口,则称这个程序是结构化的。”
上述经典定义过于狭隘了,结构程序设计本质上并不是无GO TO语句的编程方法,而是一种使程序代码容易阅读、容易理解的编程方法。在多数情况下,无GO TO语句的代码确实是容易阅读、容易理解的代码,但是,在某些情况下,为了达到容易阅读和理解的目的,反而需要使用GO TO语句。例如,当出现了错误条件时,重要的是在数据库崩溃或栈溢出之前,尽可能快地从当前程序转到一个出错处理程序,实现这个目标的最好方法就是使用前向GO TO语句(或与之等效专用语句),机械地使用3种基本控制结构实现这个目标,反而会使程序晦涩难懂。因此,下述的结构程序设计的定义可能更全面一些:“结构程序设计是尽可能少用GO TO语句的程序设计方法。最好仅在检测出错误时才使用GO TO语句,而且应该总是使用前向GO TO语句。”
虽然从理论上说只用上述3种基本控制结构就可以实现任何单入口单出口的程序,但是为了实际使用方便起见,常常还允许使用DO_UNTIL和DO_CASE两种控制结构,它们的流程图分别是图5.2(a)和图5.2(b)。
图5.2 其他常用的控制结构
(a)DO_UNTIL型循环结构 (b)多分支结构
有时需要立即从循环(甚至嵌套的循环)中转移出来,如果允许使用LEAVE(或BREAK)结构,则不仅方便而且会使效率提高很多。LEAVE或BREAK结构实质上是受限制的前向GO TO语句,用于转移到循环结构后面的语句。
如果只允许使用顺序、IF_THEN型分支和DO_WHILE型循环这3种基本控制结构,则称为经典的结构程序设计;如果除了上述3种基本控制结构之外,还允许使用DO_CASE型分支结构和DO_UNTIL型循环结构,则称为扩展的机构程序设计;如果再允许使用LEAVE(或BREAK)结构,则称为修正的结构程序设计。