770 likes | 923 Views
第 九 章 程序设计基础. 目 录. 9.1 程序 和程序设计语言 9.2 算法 9.3 程序设计 步骤与程序设计方法 9.4 常用 程序设计语言 9.5 程序设计 范型. 4.1 Word 的启动与退出. 9.1 程序和程序设计语言. 9.1.1 程序的一般概念 9.1.2 程序设计语言的概述 9.1.3 程序设计语言的结构. 甲地. B 线 5 公里. A 线 8 公里. 乙地. C 线 4 公里. 丙地. 9.1.1 程序 的一般概念. 依据实际案例并精心计算. 例: 某人从甲地到丙地去。. 步行
E N D
目 录 • 9.1 程序和程序设计语言 • 9.2 算法 • 9.3 程序设计步骤与程序设计方法 • 9.4 常用程序设计语言 • 9.5 程序设计范型
4.1 Word 的启动与退出 9.1 程序和程序设计语言
9.1.1 程序的一般概念 • 9.1.2 程序设计语言的概述 • 9.1.3 程序设计语言的结构
甲地 B线5公里 A线8公里 乙地 C线4公里 丙地 9.1.1 程序的一般概念 依据实际案例并精心计算 例:某人从甲地到丙地去。 • 步行 • 骑车 • 开车 • 时间 • 红绿灯 • 铁道 解决该计算问题的方法、步骤就包含了程序的概念。
9.1.1 程序的一般概念 • 计算机程序的概念: • 为实现某一算法而编写的指令序列。 • 宏观地描述该指令序列,可用计算机的 • 机器语言 • 汇编语言 • 高级语言 • 用经典的公式可表示为: • 程序 = 算法 + 数据结构
9.1.2 程序设计语言的概述 • 程序设计——编写程序的全过程。 • 有学者认为: • 程序设计 = 算法 + 数据结构 + 程序设计语言 • 程序设计语言——人和计算机之间对话和交流的一种工具,用于描述计算机所执行的操作。 • 计算机程序设计语言有几百种,但是最常用的不过10多种,了解一些程序设计语言的不同特性,有助于为特定任务而选择适当的程序设计语言。
9.1.2 程序设计语言的概述 • 1.机器语言(Machine Language) • 指令——指挥计算机完成某个基本操作的命令。 • 指令系统——所有的指令集合。 (第一代程序设计语言) • 机器语言——用二进制代码表示指令系统的语言。 • 机器语言程序——由二进制代码按一定规则组成的、能被机器理解和运行的指令序列。(也称可执行程序 )
9.1.2 程序设计语言的概述 • 例如:计算累加器A=8+10的机器语言程序如下:
9.1.2 程序设计语言的概述 • 2. 汇编语言(Assembly Language ) • 汇编语言——实质就是以容易记忆的代码或英文单词来代替约定的机器指令。(第二代程序设计语言) • 例如:用ADD表示加、SUB表示减、JMP表示跳转、MOV表示数据的传送指令等 。 • 汇编源程序——使用汇编语言编写的程序。
9.1.2 程序设计语言的概述 • 2. 汇编语言(Assembly Language ) • 例如:上述计算累加器A=8+10的汇编语言程序如下:
9.1.2 程序设计语言的概述 • 3. 高级语言(High Level Language) • 高级语言——类似数学语言或人的自然语言,同时又不依赖于某种计算机硬件,使得设计编制的程序能够在所有机器上通用。 (第三代程序设计语言) • 程序设计语言在不同的系统平台使用比较普遍的有:FORTRAN、ALGOL、COBOL、LISP、PL/I、BASIC、SIMULA 67、Pascal、C、Smalltalk 80、Ada、C++、VC、VB、Delphi、Java、JavaScript、C#、Visual BASIC.NET。
9.1.2 程序设计语言的概述 • 程序设计语言的特点 • 高级语言的特点: • 编程容易 • 效率低 • 需要编译系统 • 易读 • 易维护 • 汇编语言的特点: • 编程不容易 • 效率较高 • 需要汇编程序 • 不易读 • 不易维护 • 机器语言的特点: • 编程难 • 效率高 • 需要指令系统 • 难读 • 难维护
9.1.3 程序设计语言的结构 • 程序结构的多样性: • 结构化程序 • 模块化程序 • 面向对象的程序结构 • 一个良好结构的程序具有以下等特点: • 结构清晰 • 容易阅读 • 容易理解 • 容易验证 • 容易维护
入口 语句A 语句B 出口 9.1.3 程序设计语言的结构 • 1996年,计算机科学家Boehm和Jacopini提出并从数学上证明:任何一个算法,都能以三种基本控制结构表示,即顺序结构、选择结构和循环结构。 • 结构化程序设计中——顺序结构
入口 真 条件 假 语句序列A 语句序列B 出口 9.1.3 程序设计语言的结构 • 结构化程序设计中——选择结构 • 根据条件的判断确定应该执行哪一条分支的语句序列。(又称为分支结构 ) 单分支、多分支结构?
入口 入口 语句序列 真 真 条件 语句序列 假 出口 出口 当型循环结构 直到型循环结构 条件 假 9.1.3 程序设计语言的结构 • 结构化程序设计中——循环结构 • 主要用于重复执行相同的语句序列(被称为循环体),直到判定条件为假(或为真)时才可终止执行循环体。
9.1.3 程序设计语言的结构 • 结构化程序设计的特点 • 每种结构,只有一个入口和一个出口,这是结构化设计的一个原则。遵循结构化程序设计的原则,按照结构化程序设计方法设计出的程序具有明显的优点: • 其一,程序易读、理解和维护。将复杂程序分解成若干子结构,便于控制、降低程序的复杂性,因此容易编写程序,同时便于验证程序。 • 其二,提高编程工作效率,降低软件开发成本。由于结构化编程方法能够把错误控制到最低限度,因此能够减少调试和查错的时间。
9.2.1 算法的概念与特征 • 1976年Niklaus Wirth(也是Pascal语言发明者,1984年获得图灵奖)的专著: • Algorithms + Data Structures = Programs • (算法 十 数据结构 = 程序) • 在计算机软件开发行业中产生了极为深远的影响,从而推动了软件开发技术和方法步入正轨,使人们开始深入研究数据结构和算法设计与分析的技术和方法。
9.2.1 算法的概念与特征 • 算法——解决某个具体问题而采取的方法与步骤的完整和准确的描述。是指令的有限序列,其中每一条指令表示一个或多个操作。是问题的程序化解决方案,这些解决方案本身并不是答案,而是获得答案的精确指令。 • 算法的分类 • 顺序算法:是由冯·诺依曼型计算机体系结构所决定的,其主要思想是指令逐条运行,每次执行一步操作。 • 并行算法:要求在一些更新式的计算机中可以在同一时间执行多条指令。
9.2.1 算法的概念与特征 • 一个算法必须具备五项基本特征:有穷性、确定性、数据输入、数据输出和可行性。 • (1)有穷性——算法是有序指令的集合,并在执行有穷步骤后能够终止。 • (2)确定性——每条指令必须有确切的含义,且无二义性。 • (3)输入数据——可有零个或多个输入数据。这些输入数据取自于某个特定对象的集合。 • (4)输出数据——必须有一个或多个输出数据。 • (5)可行性——描述的操作都可以通过已经实现的基本运算执行有限次来实现,也可以证明整个算法实施后可以得到预期的解。
9.2.1 算法的概念与特征 • 例5.1 一个非算法的计数过程 ① 令n为0; ② 置n为n+1; ③ 返回②。 结论:不能称为算法。 原因:违背了算法特征中(1)、(4)、(5)。
9.2.1 算法的概念与特征 • 例5.2用自然语言编写一个不超过1万次的计数器算法: • ① 令n为0; • ② 置n为n+1 • ③ 若n小于10000,则返回②;否则,输出n之值,且算法到此结束。 结论:是算法。 原因:符合算法特征。 • 在算法设计过程中,其实还有有关正确性、可读性、健壮性、效率与低存储量需求,以及算法效率的度量等问题。
9.2.2 算法的描述方法 • 流程图(FlowChart) • PAD图(Problem Analysis Diafram,问题分析图) • N-S图 • 自然语言 • 伪代码 • UML图 (Unified Modeling Language,统一建模语言)
9.2.2 算法的描述方法 • 流程图 • 流程图(框图)用不同形状的几何图形表示不同性质的操作,用流程线指明算法的执行方向。ANSI(美国国家标准化协会)、ISO(国际标准化组织)和我国国家标准中均有类似的规定。常见的流程图符号如下:
9.2.2 算法的描述方法 • 向下或向右的流程线可以不画出箭头。当流程线有交叉时,则画一半圆通过交叉点。
9.2.2 算法的描述方法 • 2. PAD图 • 由日立公司推出的PAD图是一种二维图。即从上向下顺序执行,从左到右表示层次关系。表示三种基本结构的PAD图如下:
9.2.2 算法的描述方法 • 3. N-S图 • 1973年美国两位学者提出无流程线的N-S图(盒图)。 • 结构化程序设计由三种基本结构而组成,则算法也应采用结构化描述方法,N-S图的基本单元是矩形框,框内可以有三种基本结构,形如堆积木,也只有一个入口和一个出口。三种基本结构的N-S图如下:
9.2.2 算法的描述方法 • 3. N-S图 • 用N-S图描述的计数器算法
9.2.2 算法的描述方法 • 4. 自然语言 • 自然语言是人们日常生活、工作和学习中使用的通用语言,使用自然语言的文字描述算法通俗易懂,但也有它的缺陷: • (1)容易产生歧义性,因为自然语言经常要根据上下文才能判别其含义,不太严格。 • (2)自然语言很难清楚地表达算法的逻辑流程,对于算法中的条件判断、循环,尤其是在这些处理中还有多层嵌套,就很难用清晰而直观的语言来表达算法的流程。因此仅适于描述简单问题。
9.2.2 算法的描述方法 • 5. 伪代码 • 伪代码是介于自然语言和计算机语言之间的文字和符号,它不能被计算机所理解,但使用伪代码描述的算法很容易转变成某种编程语言。 • 常用的伪代码是用自然语言与类Pascal或类C语言相结合的方法来描述算法。
9.2.2 算法的描述方法 • 5. 伪代码 • //用伪代码描述的计数器算法如下: • n ← 0 • do • n ← n+1 • while n < 10000 • 输出n,且算法到此结束。
9.2.3 程序设计典型算法 • 算法——数值算法或非数值算法: • 数值算法——主要用于数值求解或分析,如:求和、求平方根、解方程、用组合梯形法则求定积分等。 • 非数值算法——主要用于各领域管理类的信息处理,如:各种排序、查找等。 • 本节介绍一些简单的常用算法,并假设各数据均能满足值域要求。
9.2.3 程序设计典型算法 • 求3个整数的最大值算法 • 为了编写求3个整数最大值的通用实现过程,采用主函数调用子函数的形式描述算法。 • (2)max3 子函数算法描述如下: • ① 从a与b中取大数送m中; • ② 从m与c中取大数送m中; • ③ 返回m给主函数。 • (1)主函数算法描述如下: • ① 输入三个整数a,b,c; • ② max = max3(a,b,c); • ③ 输出max。
9.2.3 程序设计典型算法 • 求3个整数的最大值的C程序 /*使C预编译包含I/O头文件,则可用scanf、printf函数 */ #include <stdio.h> void main(void) { int a, b, c, max; /* 定义 4 个整型变量 */ int max3(int a, int b, int c); /* max3 函数原形声明 */ printf(“Input 3 integer numbers:”);/*输出双引号中的提示信息 */ scanf(“%d%d%d”, &a, &b, &c); /*输入 3 个整数 */ max = max3(a,b,c); /* 调用 max3 函数求最大值 */ printf(“The max is: %d \n”, max); /* 输出 max 中的最大值 */ } /* End of main function */
9.2.3 程序设计典型算法 • 求3个整数的最大值的C程序 /*求 3 个整数的最大值的子函数 max3 */ int max3(inta,intb,int c) /* max3 函数将返回整型值 */ { int m; /* 定义 m 整型变量*/ if( a > b ) m = a; /* 从 a 与 b 中取大数送 m 中 */ else m = b; if( m > c ) ; /* 从 m 与 c 中取大数送 m 中,“;”即m=m */ else m = c; return(m); /* 返回 m 给主函数 */ } /* End of max3 function */
9.2.3 程序设计典型算法 • 2. 欧几里得算法 • 求解两个不全为0的非负整数m和n的最大公约数,可以采用以下欧几里得算法。 • (2)Euclid(m,n) 子函数算法描述如下: • while n ≠ 0 do • r ← m mod n • m ← n • n ← r • return m • (1)欧几里得算法主函数描述如下: • ① 输入两个不全为0的非负整数m,n; • ② Ecd = Euclid(m,n); • ③ 输出Ecd,且算法到此结束。
9.2.3 程序设计典型算法 • 3. 两个变量值的交换算法 • 计算机实现的两个变量值的交换算法如下: • ① 令 a=5, b=10 • ② c ← a, a ← b, b ← c • ③ 输出 a 和 b 的值。 void main(void) { int a=5, b=10, c; /* 定义 a、b、c 3个整型变量 */ printf(“交换前: a=%d, b=%d\n”, a, b); c = a; /*将 a 中的值赋值给 c */ a = b; /* 将 b 中的值赋值给 a */ b = c; /* 将 c 中的值赋值给 b */ printf(“交换后: a=%d, b=%d\n”, a, b); }
9.2.3 程序设计典型算法 • 4. 排序算法 • 给定一个有n个元素可排序的序列,例如数字数据或字符串数据等,要求按照升序或降序方式重新排列。 • 排序算法:如冒泡排序法、选择排序法、插入排序法、合并排序法、快速排序法等等排序算法。
9.2.3 程序设计典型算法 • 4. 排序算法 • 选择排序法降序方式排序操作过程 • 例如:对序列89,29,68,90,17,34,45操作。 | 89 29 68 90 17 34 45 90 | 29 68 89 17 34 45 90 89 | 68 29 17 34 45 90 89 68 | 29 17 34 45 90 89 68 45 | 17 34 29 90 89 68 45 34 | 17 29 90 89 68 45 34 29 | 17
9.2.3 程序设计典型算法 • 5. 查找算法 • 查找是指从给定的集合(或者是多重集,它允许几个元素具有相同的值)中查找一个给定的值(称为查找键 K)。 • 常用的查找算法有顺序查找和折半查找,还有那些将原来的集合表示为另一种形式以方便查找的算法等等。 • 顺序查找——直接从头到尾搜索集合的查找键。 • 折半查找——必须首先将集合按照降序或升序排序,然后利用折半技术搜索集合的查找键,所以,当集合是有序的时候,使用折半查找效率高、速度快。
9.3.1 程序设计步骤 一般程序设计应该包含以下4个步骤: (1)针对具体问题进行分析——了解问题性质,明确问题解决所达目标,提供的输入是什么?最终实现的输出是什么?执行中要做什么?怎么做?并建立相应的数学模型。 (2)确定数据结构并设计相应的算法——对具体问题进行概念抽象,构造出解决问题的轮廓,设计程序的数据结构和算法。
9.3.1 程序设计步骤 一般程序设计应该包含以下4个步骤: (3)编写实现算法的程序——根据算法确定解决问题的详细步骤,通常是通过绘制程序流程图,来描述问题处理的过程;然后按照流程图的描述选用某种程序设计语言编写程序。 (4)测试与调试程序——在程序设计过程中,经常不是那么一帆风顺的,尤其是初学者会遇到各种这样或那样的问题,还有一些问题可能是不可预测的,往往不得不返到上一步骤中更改或调整相应的内容,并将相应文档也一并修改,通过举一反三的方法来解决给定问题。
9.3.1 程序设计步骤 测试程序 为了发现程序中的设计错误而运行程序 。 ——所使用的测试用例尤其重要,因为不仅需要合法值域用例,而且非法值域用例也是必须的。 ——程序测试的成功与否直接可以体现程序健壮性。 ——当软件项目是由团队开发时,测试程序可分为:单元测试、组装测试和确认测试。 调试程序 错误定位和纠错的过程,这一过程的快慢与程序设计人员的编程经历和经验是密切相关的 。
开始 编辑源程序 检查确认 yes 源文件 有错? no 编译程序 yes 目标文件 有错? 其它目标文件 no 连接程序 库函数 可执行文件 有错? yes no 运行程序 yes 有错? 数据 no 结束 9.3.1 程序设计步骤 高级语言编写和运行过程
9.3.2 程序设计方法 • 早期的程序设计方法 • 早期的程序设计方法追求程序的高效率,编程过份依赖技巧,忽视程序清晰,而不注重所编写程序的结构,很少考虑程序的规范化问题,也就是没有固定程序设计方法的时期。 • 程序的可读性、可重用性都很差。其中典型问题是:频繁使用goto语句,特意算计如何节省内存空间。
9.3.2 程序设计方法 • 早期的程序设计方法 • 虽然这些方法存在很多问题,但当时受限于计算机运行速度慢、内存容量小、硬件价格昂贵,程序的规模也比较小,对于单人完成较为简单的任务,事实上这些方法还是经常被采用的。
9.3.2 程序设计方法 • 2. 结构化程序设计方法 • 结构化程序设计方法出现在70年代中期。 • 随着计算机硬件成本急剧下降,软件需要处理的复杂问题也就越来越多。 • 为了摆脱60~70年代初的软件危机,因为当时编程无章可循,程序常常带有强烈的个人色彩,程序的可读性差,程序的调试和维护更困难,促使人们认真反省和研究程序设计中一系列根本性问题: