第5章模块化程序设计
21
y=f(x),y1=f(x1)
真 y与y1同号 假 root函数
x1=x y1=y
直到 |y|<
x2=x
root=x 输出 root
2013-12-11
《解析C程序设计》第5章 模块化程序设计
弦截法求根程序
/* 定义f函数,求f(x)的值 */ float f(float x) { float y; /* 计算f(x)的值 */ y=((x-5.0)*x+16.0)*x-80.0; return(y); } /* 定义xpoint函数,求弦与x轴的交点 */ float xpoint(float x1,float x2) { float x; x=(x1*f(x2)-x2*f(x1))/ (f(x2)-f(x1)); return(x); } /* 定义root函数,求近似根 */ float root(float x1,float x2) { float x,y,y1; y1=f(x1); do { x=xpoint(x1,x2); y=f(x); /* 新的f(x)与f(x1)同号时, 用x替换x1,否则替换x2 */ if (y*y1>0) { y1=y; x1=x; }else x2=x; }while(fabs(y)>=0.0001); /* 当f(x)约等于0时退出循环 */ return(x); }
预编译命令
函数1
函数i
函数n
声明部分
《解析C程序设计》第5章 模块化程序设计
执行部分
2013-12-11
11
函数设计的原则
函数的功能要单一,不要设计多用途的函数 函数的规模要小,尽量控制在50行代码以内
1986年IBM在OS/360的研究结果:大多数有错误的函数都 大于500行 1991年对148,000行代码的研究表明:小于143行的函数比 更长的函数更容易维护
2013-12-11
《解析C程序设计》第5章 模块化程序设计
6
为什么需要模块化程序设计
什么时候需要模块化? 某一功能,如果重复实现2遍及其以上,即应考虑模块 将它写成通用函数,并向小组成员发布。
化,
要尽可能利用其它人的现成模块。
模块化程序设计方法就是按照“自顶向下、逐步求精”的思 想,将系统功能逐步细分,使每个功能非常单一,一般不超 过50行。
y f(x2)
x1 0
x
x2 x
f(x)
f(x1)
x
x1 f ( x 2 ) x 2 f ( x1 ) f ( x 2 ) f ( x1 )
2013-12-11
《解析C程序设计》第5章 模块化程序设计
20
弦截法N-S图及程序
输入x1,x2,求f(x1),f(x2) 直到f(x1)与f(x2)异 号 求f(x1)与f(x2)连线与x轴的交点x
第5章 模块化程序设计
主讲:甘玲
本章内容
1
怎样解决一个复杂的问题
模块化程序设计思想 函数的嵌套调用
2
Hanoi(汉诺)塔问题
函数的递归调用
2013-12-11
《解析C程序设计》第5章 模块化程序设计
2
5.1 怎样解决一个复杂的问题
怎样来分析和完成“高校信息管理系统” 呢? 一个大系统(或子系统)不可能用一个主 函数来完成,必须将大问题分解成小问题, 再由若干人、若干函数(模块)来完成。
修 改 信 息
录 入 信 息
修 改 信 息
学 籍 查 询
班 级 查 询
成 绩 查 询
……
2013-12-11
《解析C程序设计》第5章 模块化程序设计
4
模块化程序设计思想
为了完成上述大型系统的开发,我们将软件开发 看成是一项工程来做,其过程大致分为:系统定
义、需求分析、系统设计、编写程序、系统测试、
系统维护等阶段。 软件工程的思想:将一个大的系统采取“分而治 之”方法解决。
2013-12-11
《解析C程序设计》第5章 模块化程序设计
5
模块化程序设计思想
开发一个软件系统时,最好的办法是从编写主程 序开始,在主程序中,将问题作为一个整体考虑, 然后找出完成整个任务的主要步骤,再沿着这条 主线将整个问题继续分解为独立的模块。 这种“自顶向下、逐步细化”的思想就是模块化 程序设计的主要思想。
模块化程序设计的特点是: −各模块相对独立、功能单一、结构清晰、接口简单; −避免程序开发的重复劳动; −易于维护和功能扩充; −程序设计的复杂性得到了有效控制等。
2013-12-11 《解析C程序设计》第5章 模块化程序设计 10
C程序结构
C语言是模块化程序设计语言,每个模块都是由函数完成的,C语言是函数式 的语言,函数就是模块。使用顺序结构、分支结构、循环结构三种基本结构 设计的程序必然就是结构化程序。 C程序 源程序文件1 源程序文件i 源程序文件n
C语言就是模块化程序设计语言。
2013-12-11
《解析C程序设计》第5章 模块化程序设计
13
简化的模块化问题√
实现前面 “高校信息管理系统” ,需要用到模块 化程序设计、函数的定义、声明、调用(嵌套调用)、 返回等,还需要用到数组、指针、结构体、文件等知 识,这些知识将在后续章节逐一介绍。 这里另外提出一个稍微简单一点的问题,以便在本 节中实现。
2013-12-11
《解析C程序设计》第5章 模块化程序设计
14
提出问题
例5-1:求三个数中最大数和最小数的差 值。
2013-12-11
《解析C程序设计》第5章 模块化程序设计
15
【分析】
主函数可以调用其他函数,反之,不然。 自定义函数之间能否调用呢?能。 函数不能嵌套定义,但是函数能嵌套调用,即函 数调用函数,前者称为调用函数,后者称为被调 函数。 这里可以定义3个函数:最大值、最小值、最大 值与最小值的差,第三个函数将调用前两个函数。
2013-12-11 《解析C程序设计》第5章 模块化程序设计 9
模块化程序设计的优点
每个模块都可以分配给不同的程序员完成,从而缩短开发周期。 各个模块高聚合、模块之间低耦合,只要模块之间确定了参数 传递的接口,不管哪个模块内部的改动,均不会影响其它模块, 从而使软件产品的生产更加灵活。 系统细化到模块,条理清楚,系统更加容易理解和实现。 容易维护、系统可靠。
#include <stdio.h> #include <math.h> float f(float x); float xpoint(float x1,float x2); float root(float x1,float x2); void main() { float x1,x2,f1,f2,x; /* 输入x1和x2并保证其 函数值反号 */ do { printf("Input x1,x2:\n"); scanf("%f,%f",&x1,&x2); f1=f(x1); f2=f(x2); }while(f1*f2>=0); x=root(x1,x2); printf("A root of \ equation is \ %8.4f",x); }
C语言中的函数与模块
在C语言中,每个模块都是由函数完成的。 一个小模块就是一个函数。 在程序设计中,常将一些常用的功能模块编写成函数,放在 函数库中供公共选用。程序员要善于利用库函数,以减少重 复编写程序段的工作量。 在编写某个函数时,遇到具有相对独立的功能的程序段,都 应独立成另一个函数,而在一个函数中调用另一个函数;当 某一个函数拥有较多的代码时(一般函数代码50行左右), 也应将函数中相对独立的代码分成另一个函数。
2013-12-11
《解析C程序设计》第5章 模块化程序设计
7
模块化程序设计方法
功能分解
自顶向下、逐步求精的过程
模块分解的原则
保证模块的相对独立性
• 高聚合、低耦合
模块的实现细节对外不可见
• 外部:关心做什么 • 内部:关心怎么做
设计好模块接口
接口是指罗列出一个模块的所有的与外部打交道的变量 等 定义好后不要轻易改动 在模块开头(文件的开头)进行函数声明
2013-12-11
《解析C程序设计》第5章 模块化程序设计
3
高校信息管理系统功能分解
高校信息管理系统
人事管理 子系统
财务管理 子系统
学生管理 子系统
教学管理 子系统
设备管理 子系统
……
系统管理
学籍管理
班级管理
成绩管理
数据查询
综合测评 ……
用 户 管 理
退 出 系 统
录 入 信 息
修 改 信 息
录 入 信 息
3
9
15
2013-12-11
《解析C程序设计》第5章 模块化程序设计
19
举一反三
例5-2 用弦截法求方程的根 x 5 x 16 x 80 0
3 2
【分析】 弦截法求方程的根的方法如下: ①取两个不同点x1、x2,如果f(x1)与 f(x2)符号相反,则(x1,x2)区间内必有一 个根。否则改变x1、x2的值使得f(x1)与 f(x2)异号为止。(注意:x1与x2的值不能 相差太大,确保之间只有一个根) ②连接f(x1)与f(x2)两点,此线(即弦) 交x轴于x点(计算见图)。再求出f(x)。 ③若f(x)与f(x1)同号,则将x作为新的x1。 若f(x)与f(x2)同号,则将x作为新的x2。 ④重复第②与第③步,直到| f(x)|<, 其中是一个很小的正数,如0.0001, 此时可以认为: f(x)≈0。
/* 定义min函数求三数的最小值 */