程序设计是根据特定问题,用程序设计语言设计、编写、调试和运行程序等的过程。
程序设计的步骤一般包括分析问题和建立模型、设计算法、编写程序、调试和运行程序以及编写程序文档。
当我们用计算机来解决科学研究、工程设计、生产实践中提出的实际问题时,首先要对问题进行分析。用计算机解决问题的过程是对数据进行加工处理并输出结果的过程,因此用计算机解决问题时首先要设法把实际问题抽象成数学问题,即建立其数学模型,然后分析将哪些数据作为输入数据、要输出哪些数据等。
对问题进行详细分析和建立模型之后,便要确定解决该问题的方法和步骤,即设计算法。计算机是按照人们的意图工作的,必须详细地确定解决问题的步骤,并以适当的形式(程序)告诉计算机,计算机才能按照预定的步骤执行。如何进行算法设计以及算法的表示方法将在6.1节中详细介绍。
算法最终要以程序的形式表示出来才能上机执行。编写程序是指将第2步确定的算法和解决问题所需的数据,按照程序设计语言的语法规则编写出能在计算机上执行的源程序。
编写程序完成后,要调试和运行程序,以便找出和修改程序中的错误(如语法错误、运行错误、逻辑错误等),测试程序是否达到预期结果。
程序测试完成后,应对程序设计的过程进行总结,编写有关文档(如程序说明文档、程序代码文档、用户使用手册等)。编写程序文档已成为程序设计的必要部分,为了方便程序的管理、推广与维护,应强调每一个步骤都要有对应的规范的程序文档。
程序设计方法就是研究如何将复杂问题的求解转换为计算机能执行的简单操作的方法。
随着计算机技术的飞速发展,程序设计方法取得了很大进步。从初期的手动作坊式编程方法,经过多年的研究,发展出了多种程序设计方法,例如,自顶向下的程序设计、自底向上的程序设计、结构化程序设计、函数式程序设计、面向对象程序设计等。针对同一问题,采用的程序设计方法不同,所编写程序的可读性、可维护性、运行效率也不同。下面介绍几种目前常用的程序设计方法。
结构化程序设计(structured programming,SP)是20世纪70年代由迪杰斯特拉(Dijkstra)提出的,后来这种传统的程序设计方法得到了广泛应用。采用结构化程序设计方法设计的程序,逻辑结构清晰、层次分明、易读、易修改、易维护。其目的是解决许多人共同开发大型软件时,如何高效地实现高可靠系统的问题。
结构化程序设计是一种功能分解的方法,采用模块化设计。它采用自顶向下、逐步求精的方法,将整个系统功能逐层分解为模块,直到每个模块具有明确的功能和适当的复杂度。结构化程序设计还把程序的结构规定为顺序、选择、循环3种基本结构,限制使用goto语句。因此,系统中每个模块的功能实现应由上述3种基本结构组成。模块的划分应当遵循以下3个基本要求:
① 模块的功能在逻辑上尽可能单一、明确,最好做到一一对应,这称为模块的凝聚性;
② 模块之间的联系及相互影响尽可能地小,对于必需的联系,应当加以明确说明,这称为模块的耦合性;
③ 模块的规模应当足够小,以使编程和调试易于进行。
尽管结构化程序设计是一种应用非常广泛的程序设计方法,但随着计算机技术的飞速发展以及计算机应用的日益广泛,需要研制的系统越来越复杂,这种方法暴露出一些不足之处。首先,结构化程序设计方法是面向过程的程序设计方法,它把数据和对数据的处理过程分离为相互独立的实体,它的程序结构是“数据结构+算法”,若要修改某个数据结构,就需要改动涉及此数据结构的所有模块,所以当应用程序比较复杂时容易出错、难以维护。其次,结构化程序设计方法仍然存在与人们的思维方式不协调的地方,所以很难自然、准确地反映真实事件。
面向对象程序设计(object-oriented programming,OOP)是在20世纪80年代提出的,它源于Smalltalk语言。面向对象程序设计和面向对象的问题求解是当今计算机技术发展的重要成果和新趋势,它们是当今人们解决软件复杂性问题的新的方法。
面向对象程序设计是以对象为中心来分析问题和解决问题的。世界是由许多对象组成的,对象既可以是现实世界中独立存在、被区分的一些实体,也可以是概念上的实体。面向对象程序设计接近人们的思维方式,它丢开了持续许久的“自顶向下”和“自底向上”方法的争论,把对复杂系统的认识归结为对一批对象及其关系的认识。面向对象程序设计使用户以更自然、更简便的方式进行程序设计。
程序设计中的对象是指将数据(属性)和操作数据的方法封装在一起而形成的一种实体,这些实体具有独立的功能,并隐藏了实现这些功能的复杂性。对象之间的相互作用是通过消息传送来体现的。面向对象程序设计是一种“对象+消息”的程序设计方法,它和将大问题分解为小问题所采取的思路与结构化程序设计方法是不同的。
结构化的分解突出过程,强调的是如何做、代码的功能如何实现;面向对象的分解突出现实世界和抽象的对象,强调的是做什么,它将大量的工作交给相应的对象来完成,在应用程序中只需说明要求对象完成的任务。当然,面向对象程序设计并不是要抛弃结构化程序设计,而是站在比结构化程序设计更高、更抽象的层次上去解决问题,当问题分解到设计低级代码模块时,仍需要使用结构化编程技巧。
面向对象程序设计具有的特点是采用符合人们习惯的思维方法,程序模块化程度高,易于维护,数据十分安全,可重用性、可扩展性、可管理性强,并与可视化技术相结合改善了人机界面,等等。
程序设计语言的种类很多,编写格式和语法规则不尽相同。所以,对同一算法而言,用不同语言编写出来的程序也是不同的。但高级语言程序的基本组成成分通常可归纳为4种,即数据成分、控制成分、运算成分和传输成分。数据成分用来描述所处理的数据对象,如对数据类型和数据结构进行说明。控制成分用来表达程序中的控制结构,如条件语句、循环语句等。运算成分用来描述程序包含的运算表达式,如算术表达式和逻辑表达式等。传输成分用来表达程序中数据的传输,如I/O(input/output,输入输出)语句。在上述4种基本组成成分中,数据成分和控制成分是十分重要的组成成分,下面分别加以介绍。
数据是程序操作的对象,具有名称、类型、作用域等特征。在高级语言环境下,使用数据前要对其特征加以说明。数据名称由用户通过标识符确定,数据类型说明的是数据需要占用多少存储单元、存放方式,以及其运算合法性,作用域说明的是数据可以使用的范围。
以C语言为例,其数据类型可分为基本类型、构造类型、指针类型、空类型和用户自定义类型。其中,基本类型包括整型、实型、字符型、枚举型等;构造类型包括数组类型、结构体类型等。
例如,在程序中数值型数据是经常使用的数据,其值是一个数,数值有范围和精度要求。若它的取值是一个整数,则在程序的数据成分中可写成:
int x;
上述语句定义了x为整型变量。
控制成分的作用是提供一种基本框架,在此框架支持下,可以将数据和对数据的基本运算组合成程序。结构化程序设计方法规定了程序的3种基本结构,即顺序结构、选择结构和循环结构。由这3种基本结构所组成的算法称为结构化算法。理论上已经证明,求解任何问题的计算机程序框架都可以由这3种基本结构组成。下面分别介绍程序的3种基本结构,以及3种基本结构的实现。
(1)程序的3种基本结构
① 顺序结构。顺序结构是一种十分简单的结构,在这种结构中,各语句块(程序段)是顺序执行的,图1-4所示为顺序结构,它表示先执行操作A,再执行操作B。
图1-4 顺序结构
② 选择结构。选择结构也称为判定结构,它是根据是否满足给定的条件来选择一个语句块执行的。图1-5所示是选择结构,它表示先计算条件表达式P的值,如果P的值为真,则执行操作A;为假,则执行操作B。当选择结构中的操作A或B又由选择结构组成时,就呈现嵌套的选择结构形式。
图1-5 选择结构
③ 循环结构。循环结构又称为重复结构,它为程序描述重复计算过程提供了控制手段,它表示当满足循环的条件时,重复执行一些语句。循环结构可分为两种形式,即当型循环结构和直到型循环结构。图1-6(a)所示是当型循环结构,图1-6(b)所示是直到型循环结构。其中A表示要重复执行的操作,称为循环体;P表示控制循环体执行的条件,称为循环条件。当型循环是指当循环条件P为真时重复执行操作A,否则结束循环;直到型循环是指先执行一次操作A,然后判断循环条件P,若为假,则重复执行操作A,一直到为真时结束循环。
图1-6 循环结构
上述3种基本结构,具有以下特点:
① 每一种结构都只有一个入口和一个出口;
② 结构内的每一个部分都有机会被执行;
③ 顺序结构中的语句序列可以包含3种基本结构;
④ 结构内没有死循环。
(2)3种基本结构的实现
上述3种基本结构,在程序设计语言中有相应的语句与之对应。下面以C语言为例,介绍与上述3种基本结构对应的部分语句。
① 赋值语句。赋值语句是一种对应于顺序结构的语句,其表示形式如下:
变量名 = 表达式;
如:
a=100;
它的作用是将100赋给变量a,使得变量a的值变为100。通过赋值语句可在运行过程中改变变量的值。
② if语句。if语句是一种对应于选择结构的语句,双分支if语句的表示形式如下:
if (P) A; else B;
它表示当条件表达式P的值为真时,执行操作A,否则执行操作B。
③ while语句和for语句。while语句和for语句是对应于循环结构的语句。
while语句的表示形式如下:
while (P) A;
它表示当循环条件P的值为真时,重复执行操作A,直到P的值为假时,结束重复操作。
for语句的表示形式如下:
for (P1;P2;P3) A;
在for语句中,表达式P1表示循环变量赋初值,表达式P2表示循环控制条件,表达式P3表示循环变量增值,语句A是被重复执行的操作。
为了便于读者理解程序的基本组成成分,下面给出两个分别用C语言和Python编写的程序例子。
【例1-1】 编程实现输入两个数,按由大到小的顺序输出。
C程序代码如下:
1 main() 2 { 3 float a, b, t; 4 scanf(" %f, %f ", &a, &b); 5 if (a<b) 6 { 7 t=a; 8 a=b; 9 b=t; 10 } 11 printf(" %5.2f, %5.2f\n ", a, b); 12 }
Python程序代码如下:
1 a, b=eval(input("请输入两个数,用英文逗号隔开")) 2 if a<b: 3 a, b=b, a 4 print(a, b)
【例1-2】 编程计算1+2+3+…+100的值。
C程序代码如下:
1 main() 2 { 3 int i, s=0; 4 for (i=1; i<=100; i++) 5 s=s+i; 6 printf("%d\n", s); 7 }
Python程序代码如下:
1 s=0 2 for i in range(1, 101): 3 s=s+i 4 print(s)