15第1章概述(Introduction)该图说明,解决这个问题的程序非常具体,具体到只能适用于解决单一问题,而无通用性可言。过程控制数据输入数据处理数据输出滤数排序日期比较日期判断输入文件数组一数组二显示器图1-3过程控制结构的描述描述算法时一般总是分层描述的,因为一下子描述很细,结构上会显得有些乱。这其实就是从抽象到具体的描述过程。从理解上,也需要有些具体的数据,否则就“形象思维”不起来,这是自然的过程。当我们知道数据是下面这样的,也许就更容易想象一些:03-11-1203-08-0404-08-1102-07-0601-01-0102-05-0802-08-2303-05-22abc.txt其中的输出结果应该是:02年05月08日02年07月06日03年08月04日将复杂的过程简单地按功能分层从而达到解决问题的目的,这种思想就是过程化程序设计的思想。过程化程序设计以一系列过程的划分和组织来观察、分析和解决问题。该问题描述作为CH5的一个编程练习,供读者设计参考。www.TopSage.com
www.TopSage.com
大家网16第一部分基础编程(PartITheBasicProgramminTopSage.com1.6.2结构化程序设计(StructuredProgramming)学习程序设计方法的根本是要解决如何组织程序的问题,也即解决算法与数据的关系问题。当人们有了商业处理的需要时,就觉得FORTRAN语言有点力不从心了,于是就发明了COBOL。商业处理就是大量数据的处理工作,人们不但从语言设计上来适应应用的需要,还从编程方法上来提高解决问题的能力。N.Wirth提出的结构化程序设计思想对程序控制结构做了本质的描述。他指出,程序控制结构有三重内容,见图1-4。程序段1茶食条件程序段1程序段2程序段程序段2(a)顺序(b)选择(c)循环图1-4三种程序控制结构1.描述任何实体的操作序列只需用三种基本控制结构描述任何实体的操作序列只需用“顺序、选择、重复”这三种基本控制结构,而且这三种基本结构对描述任何问题都是足够的。可以将每个虚框看作是一个过程体,而每个过程体只有一个入口,一个出口。为避免过程体出现多个入口或出口,只要在现有的程序设计语言中避免使用goto语句(CH2.6.3),就可办到。在图1-4中:图(a)先执行程序段1,再执行程序段2,同理,执行程序段3,....(若还有其他程序段的话)。依次执行若干个程序段便构成了顺序结构。图(b)根据条件的真假,选择执行程序段1或程序段2,执行完后便到达了本过程的结束点。该图构成了程序段的选择结构,选择结构说明了程序并非要一直无条件地执行程序段,它可以在中途依条件而改变执行路径。图(c)可以根据条件的真假,规定程序段是否执行,这个事件可以反复发生,甚至永远。程序能够代替人的大量重复计算劳动,都是源自于程序的这种能力。它构成了程序段的循环结构。www.TopSage.com
www.TopSage.com
17第1章概述(Introduction)2.程序设计中的各个过程体和组成部分应以模块表示每个模块,其内聚性(aggregation)越强,外联性(association)越少,则模块独立性越好。内聚性,即模块内部所涉及的功能越单一越好。这样一旦修改起来,就职责明确了,不会因为这个原因那个原因都来找这个模块算账。外联性,即模块之间的联系越少越好,联系意味着依赖,外联性少,模块的独立性就好,独立性意味着可以独自地修改本模块而与外界无关。因此就容易编程和修改。说一个小孩独立性差,就是说他(她)不会自己拿主意,受人影响太大,也是同一个道理。减少外联性还涉及对数据的分离与归类。将过程体中的数据分离出来,独立地用数据结构去描述其数据和处理,这都是模块划分的原则。例如,在图1-3中将数据处理分成找数和排序两个模块之后,内聚性就比原来的好,因为功能更单一,外联性也改善了,因为排序过程只涉及一个容器数据而不是两个。3.过程化的程序设计方法程序设计采用从上到下,逐步细分的方法展开,即过程化的程序设计方法。在细化的过程中,应充分运用前面的过程体控制结构和模块划分原则。当然,理论归理论,在实际运用的时候,还要考虑到规模适中,不能为了模块化而将过程划分成只有一两条语句的模块。在一定的数据结构之下来设计对应算法,然后分别实现数据结构设计和算法设计,这种方法总能符合模块化的要求。因此,N.Wirth最后总结出了“程序一算法十数据结构”的形式。结构化程序曾在不大的程序规模上,起到了良好的效果。它容易编程,容易维护,容易验证程序的正确性。结构化程序设计方法主要体现在过程的功能划分与过程内部的编写规则上,因此它是一种规范的过程化程序设计思想,在这里姑且笼统地称其为过程化程序设计,或者称之为基于过程的程序设计(procedure-basedprogramming),本书中有进一步的阐述(CH7.1及 CH11.4)。1.7对象化程序设计(ObjectifiedProgramming)1.7.1基于对象的程序设计(Object-BasedProgramming)伴随着人类对计算机的依赖性日益增强,程序规模不断扩大,模块数呈指数级递增,模块间的数据传递五花八门,同一程序中模块之间的关系错综复杂,结构化程序设计的规范已经不能保证程序的正确性、可维护性和重用性了。人们开始意识到不可能在语言中内置所有待解决问题的数据结构,必须让语言具有自建数据结构的能力。数据结构对于算法对于程序是如此的重要,但当时大多数语言都没有专门支持对数据结构的直接描述。在C语言中有一种结构类型—struct,可以在单纯空间上复合其他数据类型,描述数据的组织,从而,经验丰富的程序员可以通过捆绑相应的数据操作来一定程度地达到可读、www.TopSage.com
www.TopSage.com
18第一部分基础编程(PartITheBasicProgramming)可维护的目的。但是,还是不能避免其数据操作的安全问题。在大规模程序设计中,问题尤其突出。软件发展似有一个不可逾越的极限,因此,在软件产业界曾一度有软件危机之说。浩瀚的编程大军并非每个人都必须精通问题的每个细节,这就像使用电视机的人并非都要会安装完整的电视机!恰似电视机的外壳,把电视机的内部电路和外部使用一分为二。外部使用只需了解电视机的基本操作方法,内部电路提供电视机的各项功能,两者都需要一个共同的规范一一电视机的按钮操作功能。抽象数据类型(CH11.1.2)就是想要描述这一共同的规范,它描述数据的组织和相关的操作,反映了问题的抽象模型。如果语言能够直接支持对抽象数据类型的描述,即自由定义数据类型,那么,问题就能化成以抽象数据类型为媒介的使用与实现独立的两部分,因而该语言的解决问题的能力一定就强。衡量一个语言的优劣,能否自定义或者说扩充数据类型的能力是其重要指标。C++有一个类(class)机制,这正是BjarmeStroustrup看到的C语言欠缺的地方,同时也反映了语言中对获得抽象数据类型描述能力的急迫性。数据类型的本质是数据组织和其操作的捆绑性。当对应到具体编程时,用抽象数据类型来界定,就能把编程大军分为两个阵营,一个是专业性极强的、专门实现抽象数据类型的编程,好比安装电视机者:另一个是专门使用抽象数据类型的编程,好比使用电视机者。然而,要能使抽象数据类型能够维护两大程序员阵营的编程利益,必须要在语言的设计中加入一些语言机制,这些语言机制采用了许多难以想象的技术,实现了数据封装、类型安全等,而且还必然要使代码更容易阅读和维护,否则没有人愿意用。抽象数据类型的使用,最终像使用基本数据类型那样简单,对应的实体就称之为对象。因此,编程的意义就是算法在对象之间穿梭,或日针对对象的算法设计,所以其相应的编程就是对象化的编程了。无论是实现抽象数据类型的程序员群体,还是使用抽象数据类型的程序员群体,他们都以同样的参照在工作,都在做算法设计的工作,所以更加直截了当而又具体的编程模式变成了:程序=算法+抽象数据类型在编程方法的改进中,人们首先适应了用抽象数据类型来描述数据结构。这种编程方法是基于抽象数据类型而展开的,或者说,是基于对象的程序设计。对象是程序中抽象数据类型的具体表现。算法是基于抽象数据类型的,是作用在抽象数据类型实体化的程序中的行为序列,如图1-5所示。与图1-2比较,可以看出数据类型更加多了。这些增加的数据类型,就是为了适合问题的需要,因而使得过程结构相对简单,借助于数据类型的操作,随着数据类型的重用而重用。而且其操作也标准化了,操作更有安全性。随之而来的是专业大分工:自建类型的编程工作,其专业性极强。程序员在这种专业分离的意义下进行分工,可以省去许多重复劳动,所以生产率就提高了。程序的行为表现为分层的过程结构与对象定义的集合。例如,例1-1描述的是一种分层的过程结构,其日期作为一种数据类型日期类型描述:www.TopSage.com
www.TopSage.com
1大家第1章概述(Introduction)日期外在的操作TopSage.com设定日期读取日期比较日期判定日期合法性输出日期日期内在的数据组织年,月,日double内建类型与分intClassClassClassnMas层的自建类型过程结构11图1-5对象化编程结构框架日期操作的定义在自建类型中完成,所以过程结构可以描述为图1-6。过程控制数据输入数据处理数据输出滤数排序输入文件容器容器二显示器图1-6过程控制结构www.TopSage.com
www.TopSage.com