《第5章模块化程序设计》由会员分享,可在线阅读,更多相关《第5章模块化程序设计(67页珍藏版)》请在金锄头文库上搜索。
1、第第5 5章章 模块化程序设计模块化程序设计C C语语言程序言程序设计设计讲授方法讲授方法讲授方法讲授方法解析法解析法解析法解析法u“解析法解析法”是从实际是从实际问题问题入手,剖析求解问题的入手,剖析求解问题的关关键点键点(进行知识的发现),然后结合问题讲解需要(进行知识的发现),然后结合问题讲解需要的知识点,最后给出问题的的知识点,最后给出问题的求解求解办法和实现过程,办法和实现过程,并并举一反三举一反三。u各章节以问题入手,分析并讲述需要的知识点,然各章节以问题入手,分析并讲述需要的知识点,然后再实现该问题,并通过后再实现该问题,并通过思考题思考题延伸知识点或引入延伸知识点或引入新的问题
2、,环环相扣,层层推进,充分体现解析法新的问题,环环相扣,层层推进,充分体现解析法的精髓,达到通俗易懂、由浅入深的效果,举一反的精髓,达到通俗易懂、由浅入深的效果,举一反三,培养迁移知识的能力。三,培养迁移知识的能力。 2024/8/202解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计本章内容本章内容本章内容本章内容复杂问题的求解复杂问题的求解1方程根问题方程根问题2模块化程序设计思想模块化程序设计思想 模块分解的原则模块分解的原则C程序的一般结构程序的一般结构函数的嵌套调用函数的嵌套调用阶乘问题阶乘问题 3 函数的递归调用函数的递归调用2024/8/203
3、解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计复杂问题的求解复杂问题的求解复杂问题的求解复杂问题的求解v怎样来分析和完成怎样来分析和完成“高校信息管理系统高校信息管理系统”呢?呢?v一个大系统(或子系统)不可能用一个主一个大系统(或子系统)不可能用一个主函数来完成,必须将大问题分解成小问题,函数来完成,必须将大问题分解成小问题,再由若干人、若干函数(模块)来完成。再由若干人、若干函数(模块)来完成。2024/8/204解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计高校信息管理系统功能分解高校信息管理系统功能分解高校信息
4、管理系统功能分解高校信息管理系统功能分解高校信息管理系统高校信息管理系统人人事事管管理理子系统子系统设设备备管管理理子系统子系统教教学学管管理理子系统子系统财财务务管管理理子系统子系统学学生生管管理理子系统子系统系统管理系统管理学籍管理学籍管理班级管理班级管理成绩管理成绩管理数据查询数据查询综合测评综合测评 用用户户管管理理退退出出系系统统录录入入信信息息修修改改信信息息录录入入信信息息修修改改信信息息录录入入信信息息修修改改信信息息学学籍籍查查询询班班级级查查询询成成绩绩查查询询2024/8/205解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计模块化程序
5、设计思想模块化程序设计思想模块化程序设计思想模块化程序设计思想v为了完成上述大型系统的开发,我们将软件开发为了完成上述大型系统的开发,我们将软件开发看成是一项看成是一项工程工程工程工程来做,其过程大致分为:来做,其过程大致分为:系统定系统定系统定系统定义、需求分析、系统设计、编写程序、系统测试、义、需求分析、系统设计、编写程序、系统测试、义、需求分析、系统设计、编写程序、系统测试、义、需求分析、系统设计、编写程序、系统测试、系统维护等阶段。系统维护等阶段。v软件工程的思想:将一个大的系统采取软件工程的思想:将一个大的系统采取“分而治分而治之之”方法解决。方法解决。2024/8/206解析解析C
6、程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计模块化程序设计思想模块化程序设计思想模块化程序设计思想模块化程序设计思想v开发一个软件系统时,最好的办法是从编写主程开发一个软件系统时,最好的办法是从编写主程序开始,在主程序中,将问题作为一个整体考虑,序开始,在主程序中,将问题作为一个整体考虑,然后找出完成整个任务的主要步骤,再沿着这条然后找出完成整个任务的主要步骤,再沿着这条主线将整个问题继续分解为独立的模块。主线将整个问题继续分解为独立的模块。v这种这种“自顶向下、逐步细化自顶向下、逐步细化”的思想就是模块化程的思想就是模块化程序设计的主要思想。序设计的主要思想。2
7、024/8/207解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计为什么需要模块化程序设计为什么需要模块化程序设计为什么需要模块化程序设计为什么需要模块化程序设计v什么时候需要模块化?什么时候需要模块化? 某一功能,如果重复实现某一功能,如果重复实现2遍及其以上,即应考虑模块遍及其以上,即应考虑模块 化,化,将它写成通用函数,并向小组成员发布。将它写成通用函数,并向小组成员发布。v要尽可能利用其它人的现成模块。要尽可能利用其它人的现成模块。v模块化程序设计方法就是按照模块化程序设计方法就是按照“自顶向下、逐步求精自顶向下、逐步求精”的思想,的思想,将系统功能
8、逐步细分,使每个功能非常单一,一般不超过将系统功能逐步细分,使每个功能非常单一,一般不超过50行。行。2024/8/208解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计模块化程序设计方法模块化程序设计方法模块化程序设计方法模块化程序设计方法v功能分解功能分解自顶向下、逐步求精的过程v模块分解的原则模块分解的原则保证模块的相对独立性高聚合、低耦合模块的实现细节对外不可见外部:关心做什么内部:关心怎么做v设计好模块接口设计好模块接口接口是指罗列出一个模块的所有的与外部打交道的变量等 定义好后不要轻易改动在模块开头(文件的开头)进行函数声明2024/8/209解
9、析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计模块分解的原则模块分解的原则模块分解的原则模块分解的原则v模块分解的基本原则是:高聚合、低耦合及信息隐藏。模块分解的基本原则是:高聚合、低耦合及信息隐藏。v高聚合是指一个模块只能完成单一的功能,不能高聚合是指一个模块只能完成单一的功能,不能“身身兼数职兼数职”,在描述功能时不能出现,在描述功能时不能出现“和和”、“与与”等等连词。连词。v低耦合是指模块之间参数传递尽量少,还不能通过全低耦合是指模块之间参数传递尽量少,还不能通过全局变量来实现数据传递。局变量来实现数据传递。v信息隐藏是指把不需要调用者知道的信息都包
10、装在模信息隐藏是指把不需要调用者知道的信息都包装在模块内部隐藏起来。块内部隐藏起来。v只有实现了高聚合、低耦合,才可能最大程度的实现只有实现了高聚合、低耦合,才可能最大程度的实现信息隐藏,从而实现真正意义上的模块化程序设计。信息隐藏,从而实现真正意义上的模块化程序设计。2024/8/2010解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计模块化程序设计的优点模块化程序设计的优点模块化程序设计的优点模块化程序设计的优点v每个模块都可以分配给不同的程序员完成,从而缩短开发周期。每个模块都可以分配给不同的程序员完成,从而缩短开发周期。v各个模块高聚合、模块之间低耦
11、合,只要模块之间确定了参数各个模块高聚合、模块之间低耦合,只要模块之间确定了参数传递的接口,不管哪个模块内部的改动,均不会影响其它模块,传递的接口,不管哪个模块内部的改动,均不会影响其它模块,从而使软件产品的生产更加灵活。从而使软件产品的生产更加灵活。v系统细化到模块,条理清楚,系统更加容易理解和实现。系统细化到模块,条理清楚,系统更加容易理解和实现。v容易维护、系统可靠。容易维护、系统可靠。v模块化程序设计的特点是:模块化程序设计的特点是:各模块相对独立、功能单一、结构清晰、接口简单;各模块相对独立、功能单一、结构清晰、接口简单;避免程序开发的重复劳动;避免程序开发的重复劳动;易于维护和功能
12、扩充;易于维护和功能扩充;程序设计的复杂性得到了有效控制等。程序设计的复杂性得到了有效控制等。2024/8/2011解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计C C程序的一般结构程序的一般结构程序的一般结构程序的一般结构C C语言是模块化程序设计语言,每个模块都是由函数完成的,语言是模块化程序设计语言,每个模块都是由函数完成的,C C语言是函数式语言是函数式的语言,函数就是模块。使用顺序结构、分支结构、循环结构三种基本结构的语言,函数就是模块。使用顺序结构、分支结构、循环结构三种基本结构设计的程序必然就是结构化程序。设计的程序必然就是结构化程序。 C程
13、序程序源程序文件源程序文件1源程序文件源程序文件i源程序文件源程序文件n预编译命令预编译命令函数函数1函数函数i函数函数n函数声明部分函数声明部分函数执行部分函数执行部分2024/8/2012解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计函数设计的原则函数设计的原则函数设计的原则函数设计的原则v函数的功能要单一,不要设计多用途的函数函数的功能要单一,不要设计多用途的函数 v函数的规模要小,尽量控制在函数的规模要小,尽量控制在50行代码以内行代码以内1986年IBM在OS/360的研究结果:大多数有错误的函数都大于500行1991年对148,000行代码的研
14、究表明:小于143行的函数比更长的函数更容易维护v参数和返回值的规则参数和返回值的规则参数要书写完整,不要省略对函数的入口参数进行有效性检查没有参数和返回值时,用void填充每个函数只有一个入口和一个出口,尽量不使用全局变量尽量少用静态局部变量,以避免函数具有“记忆”功能2024/8/2013解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计C C语言中的函数与模块语言中的函数与模块语言中的函数与模块语言中的函数与模块v在在C语言中,每个模块都是由函数完成的。语言中,每个模块都是由函数完成的。v一个小模块就是一个函数。一个小模块就是一个函数。v在程序设计中,常
15、将一些常用的功能模块编写成函数,放在在程序设计中,常将一些常用的功能模块编写成函数,放在函数库中供公共选用。程序员要善于利用函数库中供公共选用。程序员要善于利用库函数库函数,以减少重,以减少重复编写程序段的工作量。复编写程序段的工作量。v在编写某个函数时,遇到具有相对独立的功能的程序段,都在编写某个函数时,遇到具有相对独立的功能的程序段,都应独立成另一个函数,而在一个函数中调用另一个函数;当应独立成另一个函数,而在一个函数中调用另一个函数;当某一个函数拥有较多的代码时(一般函数代码某一个函数拥有较多的代码时(一般函数代码50行左右),行左右),也应将函数中相对独立的代码分成另一个函数。也应将函
16、数中相对独立的代码分成另一个函数。vC语言就是模块化程序设计语言。语言就是模块化程序设计语言。2024/8/2014解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计简化的模块化问题简化的模块化问题简化的模块化问题简化的模块化问题v实现前面实现前面 “高校信息管理系统高校信息管理系统” ,需要用到模块化,需要用到模块化程序设计、函数的定义、声明、调用(嵌套调用)、程序设计、函数的定义、声明、调用(嵌套调用)、返回等,还需要用到数组、指针、结构体、文件等知返回等,还需要用到数组、指针、结构体、文件等知识,这些知识将在后续章节逐一介绍。识,这些知识将在后续章节逐一
17、介绍。v这里另外提出一个稍微简单一点的问题,以便在本这里另外提出一个稍微简单一点的问题,以便在本节中实现。节中实现。2024/8/2015解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计提出问题提出问题提出问题提出问题v【例例5-1】求一元二次方程求一元二次方程ax2+bx+c的根,并的根,并考虑判别式的各种情况。考虑判别式的各种情况。2024/8/2016解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计主函数可以调用其他函数,反之,不然。主函数可以调用其他函数,反之,不然。v自定义函数之间能否调用呢?能。自定义函数之间能
18、否调用呢?能。v函数不能嵌套定义,但是函数能嵌套调用,即函函数不能嵌套定义,但是函数能嵌套调用,即函数调用函数,前者称为数调用函数,前者称为调用函数调用函数,后者称为,后者称为被调被调函数函数。v在主函数在主函数main()中输入中输入a、b、c,并调用求根,并调用求根函数函数root();在求根函数中再计算判别式;在求根函数中再计算判别式disc,并判断并判断3种情况,根据每种情况调用不同的根计种情况,根据每种情况调用不同的根计算函数算函数root1()、root2()、root3()。 分析问题分析问题分析问题分析问题2024/8/2017解析解析C程序设计(第程序设计(第2版)第版)第5
19、章章 模块化程序设计模块化程序设计实现代码实现代码实现代码实现代码v/* LI5_1.C */v#include v#include v/* 自定义函数的声明自定义函数的声明 */vvoid root(int a,int b,int c); vfloat root1(int a,int b,int c);vvoid root2(int a,int b,int c);vvoid root3(int a,int b,int c);v/* 主函数主函数 */vint main() vvint a,b,c;v printf(Input a,b,c: );v scanf(%d,%d,%d,&a,&b,&
20、c);v root(a,b,c); /* 调用求方程根函数调用求方程根函数 */v return 0;v2024/8/2018解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计v/* 求方程根函数求方程根函数 */ vvoid root(int a,int b,int c)vvfloat disc,r;v disc=b*b-4*a*c; /* 求判别式的值求判别式的值 */v if(disc=0)v vr=root1(a,b,c); /* 调用求两个相等实根函数调用求两个相等实根函数 */v printf(x1=%7.2ftx2=%7.2fn,r,r);v v
21、 else if(disc0)v root2(a,b,c); /* 调用求两个不相等实根函数调用求两个不相等实根函数 */v elsev root3(a,b,c); /* 调用求两个虚根函数调用求两个虚根函数 */vv/* 求方程两个相等实根函数求方程两个相等实根函数 */vfloat root1(int a,int b,int c)vvfloat r;v r=(-b)/(2.0*a); /* 计算相等的实根计算相等的实根 */v return(r); v 2024/8/2019解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计v/* 求方程两个不相等实根函数
22、求方程两个不相等实根函数 */vvoid root2(int a,int b,int c)vvfloat disc,x1,x2;v disc=b*b-4*a*c;v x1=(-b+sqrt(disc)/(2.0*a); /* 计算实根计算实根x1 */v x2=(-b-sqrt(disc)/(2.0*a); /* 计算实根计算实根x2 */v printf(x1=%7.2ftx2=%7.2fn,x1,x2);vv/* 求方程两个虚根函数求方程两个虚根函数 */vvoid root3(int a,int b,int c) vvfloat disc,p,q;v disc=b*b-4*a*c;v p
23、=-b/(2.0*a); /* 计算虚根实部计算虚根实部p */v q=sqrt(-disc)/(2.0*a); /* 计算虚根虚部计算虚根虚部q */v printf(x1=%7.2f+%7.2fitx2=%7.2f-%7.2fin,p,q,p,q);v2024/8/2020解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计图图5-3 5-3 例例5-15-1函数调用关系示意图函数调用关系示意图main()root()root()root1()root1()库函数库函数root2()root2()库函数库函数root3()root3()库函数库函数函数调用函
24、数调用函数调用函数调用2024/8/2021解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计函数的嵌套调用函数的嵌套调用函数的嵌套调用函数的嵌套调用main( )调用函数调用函数a结束结束a函数函数b函数函数调用函数调用函数b2024/8/2022解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计课堂练习课堂练习课堂练习课堂练习v用函数的嵌套调用方法计算:用函数的嵌套调用方法计算:2024/8/2023解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计举一反三举一反三举一反三举一反三/*LI
25、5_2.c*/*LI5_2.c*/#include #include int dif(int x,int y,int z);int dif(int x,int y,int z);int max(int x,int y,int z);int max(int x,int y,int z);int min(int x,int y,int z);int min(int x,int y,int z);void main()void main() int a,b,c,d; int a,b,c,d; printf(Input Data: ); printf(Input Data: ); scanf(%d%d
26、%d,&a,&b,&c); scanf(%d%d%d,&a,&b,&c); d=dif(a,b,c); d=dif(a,b,c); printf(Max-Min=%dn,d); printf(Max-Min=%dn,d); /* /* 定义定义difdif函数求三数的差值函数求三数的差值 * */ /int dif(int x,int y,int z)int dif(int x,int y,int z) int m1,m2; int m1,m2; m1= max(x,y,z); m1= max(x,y,z); m2= min(x,y,z); m2= min(x,y,z); return m1-
27、m2; return m1-m2; /* /* 定义定义maxmax函数求三数的最大值函数求三数的最大值 * */ /int max(int x,int y,int z)int max(int x,int y,int z) int r1,r2; int r1,r2; r1=(xy)?x:y; r1=(xy)?x:y; r2=(r1z)?r1:z; r2=(r1z)?r1:z; return(r2); return(r2); /* /* 定义定义minmin函数求三数的最小值函数求三数的最小值 * */ /int min(int x,int y,int z)int min(int x,int y
28、,int z) int r; int r; r=(xy)?x:y; r=(xy)?x:y; return(rz?r:z); return(rz?r:z); main( )调用函数调用函数dif输出输出结束结束dif函数函数max函数函数调用函数调用函数max调用函数调用函数minmin函数函数2024/8/2024解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计举一反三举一反三举一反三举一反三例例5-3 用弦截法求方程的根用弦截法求方程的根【分析分析】弦截法求方程的根的方法如下:弦截法求方程的根的方法如下:取两个不同点取两个不同点x x1 1、x x2 2,
29、如果如果f(xf(x1 1) )与与f(xf(x2 2) )符号相反,则符号相反,则(x(x1 1,x,x2 2) )区间内必有一区间内必有一个根。否则改变个根。否则改变x x1 1、x x2 2的值使得的值使得f(xf(x1 1) )与与f f(x(x2 2) )异号为止。(注意:异号为止。(注意:x x1 1与与x x2 2的值不能的值不能相差太大,确保之间只有一个根)相差太大,确保之间只有一个根)连接连接f(xf(x1 1) )与与f(xf(x2 2) )两点,此线两点,此线( (即弦即弦) )交交x x轴于轴于x x点点( (计算见图计算见图) )。再求出。再求出f(x)f(x)。若若
30、f(x)f(x)与与f(xf(x1 1) )同同号,则将号,则将x x作为新的作为新的x x1 1。若若f(x)f(x)与与f(xf(x2 2) )同号,则将同号,则将x x作为新的作为新的x x2 2。重复第重复第与第与第步,直到步,直到| f(x)f(x)| ,其中其中 是一个很小的正数,如是一个很小的正数,如0.0001,此时可以认为:此时可以认为: f(x)0f(x)0。xyf(x)0x1x2xf(x1)f(x2)2024/8/2025解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计弦截法弦截法弦截法弦截法N-SN-S图及程序图及程序图及程序图及程序
31、求求f(x1)与与f(x2)连线与连线与x轴的交点轴的交点x输入输入x1,x2,求求f(x1),f(x2)直到直到f(x1)与与f(x2)异异号号y=f(x),y1=f(x1)y与与y1同号同号真真假假x1=xy1=yx2=x直到直到 |y| root=x 输出输出 rootroot函数函数#include #include #include #include float f(float x); float f(float x); float xpoint(float x1,float float xpoint(float x1,float x2);x2);float root(float x
32、1,float x2);float root(float x1,float x2);void main()void main() float x1,x2,f1,f2,x; float x1,x2,f1,f2,x; /* /* 输入输入x1x1和和x2x2并保证其并保证其 函数值反号函数值反号 * */ / do do printf(Input printf(Input x1,x2:n);x1,x2:n); scanf(%f,%f,&x1,&x2);scanf(%f,%f,&x1,&x2); f1=f(x1); f1=f(x1); f2=f(x2); f2=f(x2); while(f1*f2=
33、0); while(f1*f2=0); x=root(x1,x2); x=root(x1,x2); printf(A root of printf(A root of equation is equation is %8.4f,x); %8.4f,x); 2024/8/2026解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计弦截法求根程序弦截法求根程序弦截法求根程序弦截法求根程序/* 定义定义f函数,求函数,求f(x)的值的值 */float f(float x) float y; /* 计算计算f(x)的值的值 */ y=(x-5.0)*x+16.0)*x
34、-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
35、*/ if (y*y10) y1=y; x1=x; else x2=x; while(fabs(y)=0.0001); /* 当当f(x)约等于约等于0时退出循环时退出循环 */ return(x);2024/8/2027解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计函数调用关系函数调用关系函数调用关系函数调用关系main()调用函数调用函数root结束结束函数函数root调用函数调用函数f函数函数f调用函数调用函数xpoint函数函数xpoint函数函数f调用函数调用函数f图图5-7例例5-3函数嵌套调用示函数嵌套调用示意图意图2024/8/2028解析
36、解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-45-4求求的值。的值。【分析分析】从表达式中可以看出,每项都是一样的,不同的是起止数从表达式中可以看出,每项都是一样的,不同的是起止数不同,因此每项的计算可以由一个相同的函数来完成。而不同,因此每项的计算可以由一个相同的函数来完成。而每项中还有一个阶乘,因此还需要一个求阶乘的函数。每项中还有一个阶乘,因此还需要一个求阶乘的函数。 2024/8/2029解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-45-4程序程序程序程序#include #includ
37、e /* /* 求求n n的阶乘函数的阶乘函数 * */ /double fac(int n) double fac(int n) double s=n; double s=n; if(n=1) if(n=1) return 1; /* return 1; /* 小于小于1 1的数的阶乘都返回的数的阶乘都返回1 */1 */ for( ; -n; ) /* for( ; -n; ) /* 先将先将n n值减值减1 1,再判断,再判断n n值是否为非值是否为非0 0(真)(真) * */ / s *= n; /* s *= n; /* 计算阶乘计算阶乘s=s*n s=s*n ,计算的是:,计算的
38、是:s=n*(n-1)*s=n*(n-1)*2*1 */*2*1 */ return s; /* return s; /* 返回返回n!n!值值 * */ / /* /* 求项的值:求项的值:n1n1和和n2n2为起止数为起止数 * */ /double sum (int n1, int n2) double sum (int n1, int n2) int i; int i; double s=0; double s=0; for (i=n1;i=n2;i+) for (i=n1;i 1) /* 递归方式递归方式 */2024/8/2033解析解析C程序设计(第程序设计(第2版)第版)第5章
39、章 模块化程序设计模块化程序设计v递归算法的执行过程分递归算法的执行过程分回推和递推回推和递推回推和递推回推和递推两个阶段:两个阶段:在回推阶段,把较复杂的问题(规模为n)的求解推到比原问题简单一些的问题(规模小于n)的求解;在递推阶段,当获得最简单情况的解后,逐级返回,依次得到稍复杂问题的解。v计算计算5!其递归过程中的!其递归过程中的“回推回推”和和“递推递推”,如图如图5-9所示。所示。2024/8/2034解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计“ “回推回推回推回推” ”和和和和“ “递推递推递推递推” ”5!54!43!32!21!15!
40、4!53!42!31!21回推过程返回1返回1!22返回2!36返回3!424返回4!5120终值120递推过程调用函数函数返回值2024/8/2035解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计求解过程求解过程求解过程求解过程对使用递归方法计算对使用递归方法计算4!的结果如下:!的结果如下: 调用调用 递归调用递归调用 返回返回第第1步步 fac(4) fa=4*fac(4-1)=4*fac(3) fa=4*3*2*1第第2步步 fac(3) fa=3*fac(3-1)=3*fac(2) fa=3*2*1第第3步步 fac(2) fa=2*fac(2-
41、1)=2*fac(1) fa=2*1第第4步步 fac(1) fa=fac(1)=1回推回推递推递推 回推过程:计算回推过程:计算fac(4)时要知道时要知道fac(3),计算计算fac(3)时要知道时要知道fac(2),计计算算fac(2)时要知道时要知道fac(1),而,而fac(1)为为1。 递推过程:知道递推过程:知道fac(1)后可算后可算fac(2),从而可算从而可算fac(3),最后计算最后计算fac(4)。2024/8/2036解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-55-5程序程序程序程序/*LI5_5.c*/#incl
42、ude long fac(int n); void main() int n; long r; /* 定义长整型变量存放定义长整型变量存放n的阶乘的值的阶乘的值 */ printf(Input n: ); scanf(%d,&n); if(n0) /* 当当n正确时求阶乘,错误时则提示正确时求阶乘,错误时则提示*/ printf(Input Data error(n1n1) /* /* 递归方式递归方式 * */ /【分析分析】由公式可以看出,第由公式可以看出,第n项斐波那契数列值是前项斐波那契数列值是前2项的和,这就是项的和,这就是递归方式;而当递归方式;而当n=0和和1时,斐波那契数列就是
43、时,斐波那契数列就是n值本身,这就值本身,这就是递归结束条件。是递归结束条件。2024/8/2043解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-65-6程序程序程序程序/*LI5_6.c*/#include void main() long fib(int n); /* 自定义函数声明自定义函数声明 */ long s; /* 第第 i 项斐波那契数列的值项斐波那契数列的值 */ int i=0; /* 斐波那契数列某项的序号斐波那契数列某项的序号 */ do s=fib(i); /* 求斐波那契数列第求斐波那契数列第 i 项项 */ pri
44、ntf(Fib(%d)=%ldn,i,s); /* 显示斐波那契数列第显示斐波那契数列第 i 项的值项的值 */ printf(Input Fibonacci Number:); scanf(%d,&i); /* 输入要求的某一项的序号输入要求的某一项的序号 */ while(i0); /* 循环输入序号,直到循环输入序号,直到i值小于等于值小于等于0 */* 定义求第定义求第n项斐波那契数列值的函数项斐波那契数列值的函数*/long fib(int n) if(n=0|n=1) /* 判断是否为结束条件判断是否为结束条件 */ return n; else return fib(n-2)+f
45、ib(n-1); /* 求斐波那契数列的递归方式求斐波那契数列的递归方式 */2024/8/2044解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-65-6程序说明程序说明程序说明程序说明本例中自定义函数的声明本例中自定义函数的声明long fib(int n); 放在放在main函数函数中,因此,中,因此,fib函数只能在函数只能在main函数中使用,在其他函数中使函数中使用,在其他函数中使用时还需要再次声明。用时还需要再次声明。Fibonacci数列递归调用的次数随项数的增多而呈指数级数数列递归调用的次数随项数的增多而呈指数级数的增长。每次递
46、归调用的增长。每次递归调用fib函数时,都要调用该函数两次。即计函数时,都要调用该函数两次。即计算算n个个Fibonacci数列的值,递归调用的次数为数列的值,递归调用的次数为2n 。计算第。计算第20项的项的Fibonacci数需要递归调用的次数为数需要递归调用的次数为220 (大约大约100万次万次),计算第,计算第4项则只需要项则只需要16次。这种现象称为指数复杂度。次。这种现象称为指数复杂度。虽然程序的算法简单,但计算的复杂度会随着虽然程序的算法简单,但计算的复杂度会随着n的增加而呈指的增加而呈指数级增长。数级增长。2024/8/2045解析解析C程序设计(第程序设计(第2版)第版)第
47、5章章 模块化程序设计模块化程序设计HanoiHanoi(汉诺)塔问题(汉诺)塔问题(汉诺)塔问题(汉诺)塔问题例例5-4 编程求解编程求解Hanoi(汉诺)塔问题。(汉诺)塔问题。古代有一个梵塔,塔内有三个柱子古代有一个梵塔,塔内有三个柱子A、B、C,僧侣们想把,僧侣们想把A拄子上的一摞盘子移动到拄子上的一摞盘子移动到C柱子上。最初柱子上。最初A拄子上有大小不等的拄子上有大小不等的64个盘子,且小的在上,大的在下。在移动过个盘子,且小的在上,大的在下。在移动过程中,大盘子只能在下,小盘子只能在上,并且每次只能移动一个盘子,可以借助于程中,大盘子只能在下,小盘子只能在上,并且每次只能移动一个盘
48、子,可以借助于B柱子。柱子。6463621ABC2024/8/2046解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计问题的分析问题的分析问题的分析问题的分析Hanoi(汉诺)塔问题是一个古典的数学问题,任何一个人都不可能使用(汉诺)塔问题是一个古典的数学问题,任何一个人都不可能使用传统的方法直接写出移动盘子的每一个具体步骤,僧侣们也无法解决这传统的方法直接写出移动盘子的每一个具体步骤,僧侣们也无法解决这个问题。个问题。 解决解决Hanoi(汉诺)塔问题的方法可以表述如下:(汉诺)塔问题的方法可以表述如下:v老和尚移动老和尚移动64个盘子的步骤个盘子的步骤v
49、第第1步,请第步,请第2个和尚将前个和尚将前63个盘子从个盘子从A柱子移到柱子移到B柱子;柱子;v第第2步,自己将最下面的第步,自己将最下面的第64个盘子从个盘子从A柱子移到柱子移到C柱子;柱子;v第第3步,再请第步,再请第2个和尚将个和尚将63个盘子从个盘子从B柱子移到柱子移到C柱子。柱子。v第第2个和尚移动个和尚移动63个盘子的步骤个盘子的步骤v第第1步,请第步,请第3个和尚将前个和尚将前62个盘子从个盘子从A柱子移到柱子移到C柱子;柱子;v第第2步,自己将最下面的第步,自己将最下面的第63个盘子从个盘子从A柱子移到柱子移到B柱子;柱子;v第第3步,再请第步,再请第3个和尚将个和尚将62个
50、盘子从个盘子从C柱子移到柱子移到B柱子。柱子。v依此类推,直到第依此类推,直到第63个和尚完成了个和尚完成了2个盘子的移动,最后由第个盘子的移动,最后由第64个和个和尚完成尚完成1个盘子的移动。这个过程称之为个盘子的移动。这个过程称之为“回推回推”过程。过程。2024/8/2047解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计问题的分析问题的分析问题的分析问题的分析v当第当第64个和尚完成个和尚完成1个盘子的移动后,第个盘子的移动后,第63个和尚就可个和尚就可以完成以完成2个盘子的移动,个盘子的移动,最后第,最后第1个和尚完成个和尚完成64个盘子的移动。这
51、个过程称之为个盘子的移动。这个过程称之为“递推递推”过程。过程。v“回推回推”和和“递推递推”两个过程构成了两个过程构成了“递归递归”问题的两问题的两个阶段。如果要求递归过程在有限步骤内,就必须有一个阶段。如果要求递归过程在有限步骤内,就必须有一个结束递归过程的条件。个结束递归过程的条件。Hanoi(汉诺)塔问题就是第(汉诺)塔问题就是第64个和尚可以一次性的完成盘子的移动,个和尚可以一次性的完成盘子的移动,Hanoi(汉(汉诺)塔问题只有采用递归方法才能非常容易的、有效的诺)塔问题只有采用递归方法才能非常容易的、有效的得到解决。得到解决。2024/8/2048解析解析C程序设计(第程序设计(
52、第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-45-4汉诺塔问题的实现汉诺塔问题的实现汉诺塔问题的实现汉诺塔问题的实现用用A、B、C分别表示分别表示Hanoi(汉诺)塔中的三个柱子,(汉诺)塔中的三个柱子,1n表示表示n个盘子,个盘子,最上面的编号为最上面的编号为1,最下面的编号为,最下面的编号为n。首先设计一个函数首先设计一个函数move完成将第完成将第k个盘子从个盘子从A柱子移动到柱子移动到C柱子,即模拟和柱子,即模拟和尚自己移动一个盘子。尚自己移动一个盘子。move(int no,char from,char to); 整型变量整型变量no表示盘子的编号,字符型变量表示
53、盘子的编号,字符型变量from表示源柱子,字符型变量表示源柱子,字符型变量to表示目的表示目的柱子。柱子。再设计一个函数再设计一个函数hanoi完成将完成将n个盘子从个盘子从A柱子移动到柱子移动到C柱子,即和尚请另外柱子,即和尚请另外一个和尚移动盘子的过程。一个和尚移动盘子的过程。hanoi(int n,char A,char B,char C); 表示表示借助借助B柱子将柱子将n个盘子从个盘子从A柱子移动到柱子移动到C柱子。柱子。将将n个盘子借助个盘子借助B柱子从柱子从A柱子移动到柱子移动到C柱子,可以使用三个步骤实现:柱子,可以使用三个步骤实现:步骤步骤1:hanoi(n-1,A,C,B)
54、; /* 借助借助C柱子将柱子将n-1个盘子从个盘子从A移到移到B */步骤步骤2:move(n,A,C); /* 将第将第n个盘子从个盘子从A柱子移动到柱子移动到C柱子柱子 */步骤步骤3:hanoi(n-1,B,A,C); /* 借助借助A柱子将柱子将n-1个盘子从个盘子从B移到移到C */2024/8/2049解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-45-4程序程序程序程序/*LI5_4.c*/#include /* 包含头文件包含头文件 */void move(int no,char from,char to); /* 自定义函数
55、的声明自定义函数的声明 */void hanoi(int n,char A,char B,char C); /* 自定义函数的声明自定义函数的声明 */void main() /* 主函数,无参数,无返回值主函数,无参数,无返回值 */ int n; /* 定义整型变量定义整型变量n,存放盘子总数,存放盘子总数 */ printf(Input the number of diskes: ); /* 提示输入提示输入n的值的值 */ scanf(%d,&n); /* 输入输入n的值的值 */ printf(The step to moving %3d diskes:n,n); hanoi(n,A
56、,B,C); /* 借助借助B柱子将柱子将n个盘子从个盘子从A移到移到C */* 定义函数:显示移动过程定义函数:显示移动过程 int no:表示第:表示第no个盘子个盘子 char from:表示源柱子:表示源柱子 char to:表示目的柱子:表示目的柱子*/void move(int no,char from,char to) printf(Move %3d : %c %cn,no,from,to);/* 定义函数:定义函数: 借助借助B柱子将柱子将n个盘子从个盘子从A柱子移动到柱子移动到C柱子柱子 int n:表示:表示n个盘子个盘子 char A:表示:表示A柱子柱子 char B:
57、表示:表示B柱子柱子 char C:表示:表示C柱子柱子*/void hanoi(int n,char A,char B,char C) if (n=1) move(n,A,C); else hanoi(n-1, A,C,B); move(n,A,C); hanoi(n-1,B,A,C); 2024/8/2050解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-45-4程序说明程序说明程序说明程序说明v本程序递归函数没有返回值,只是完成了三个步本程序递归函数没有返回值,只是完成了三个步骤,并将结果输出显示在屏幕上。骤,并将结果输出显示在屏幕上。v在
58、本程序中,递归结束条件是当在本程序中,递归结束条件是当n=1时所执行时所执行的移动的移动1个盘子的函数;递归方式是先将个盘子的函数;递归方式是先将n-1个个盘子移动到盘子移动到B柱子,再将第柱子,再将第n个盘子移动到个盘子移动到C柱柱子,最后将子,最后将n-1个盘子移动到个盘子移动到C柱子。柱子。v本程序没有明确的递归公式,也没有初值和递归本程序没有明确的递归公式,也没有初值和递归函数的返回值。函数的返回值。v本程序中本程序中move函数并未真正移动盘子,只是打函数并未真正移动盘子,只是打印出移动盘子的方案。印出移动盘子的方案。2024/8/2051解析解析C程序设计(第程序设计(第2版)第版
59、)第5章章 模块化程序设计模块化程序设计举一反三举一反三举一反三举一反三例例5-7 用递归法编写一函数将一个整数用递归法编写一函数将一个整数n转换成若干字符显示转换成若干字符显示在屏幕上。例如整数在屏幕上。例如整数-258转换成转换成4个字符个字符“-258”显示。显示。 【分析分析】如果整数为正数,如如果整数为正数,如258,显示时不需要符号,而为,显示时不需要符号,而为负数时,则需要负号负数时,则需要负号“”。每位数字转换成字符时,只需要。每位数字转换成字符时,只需要将数字加上字符将数字加上字符“0”即可;而将数字字符转换成数字时,只需即可;而将数字字符转换成数字时,只需要将数字字符减去字
60、符要将数字字符减去字符“0”即可。如:字符即可。如:字符9要变成数字要变成数字9,只需要作只需要作9-0运算,即:运算,即:9=9-0;数字;数字9要变成字符要变成字符9,只需要作只需要作0+9运算,即:运算,即:9=0+9。n/10是将是将n缩小缩小10倍,为求倍,为求n的十位数作准备,的十位数作准备,n%10是求是求n的个位数,如此循环(递归),可以将的个位数,如此循环(递归),可以将n的每位数字求出。的每位数字求出。 2024/8/2052解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-75-7程序程序程序程序递归调用递归调用convert
61、函数输出字符函数输出字符输入整数输入整数number使使number变为正数变为正数number0输出负号输出负号TF/*LI5_7.c*/#include void convert(int n);void main() int number; printf(Input number:); scanf(%d,&number); printf(nOutput is:); if (numberb,则,则a和和b的最大公约数与的最大公约数与a-b和和b的最大公约数的最大公约数相同;相同;如果如果ba,则,则a和和b的最大公约数与的最大公约数与a和和b-a的最大公约数相的最大公约数相同;同;如果如果a
62、=b,则,则a和和b的最大公约数与的最大公约数与a值和值和b值相同。换句话值相同。换句话说,最大公约数是最后能使余数为说,最大公约数是最后能使余数为0的被除数。的被除数。最小公倍数为:两数相乘,再除以最大公约数。最小公倍数为:两数相乘,再除以最大公约数。 2024/8/2055解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计解法一:穷举法解法一:穷举法解法一:穷举法解法一:穷举法/*LI5_8_1.c*/#include #include int hcf(int u,int v);int lcd(int u,int v,int h);void main()
63、int n1,n2,h,l; clrscr(); /* 清屏清屏 */ scanf(%d,%d,&n1,&n2); /* 输入两个数输入两个数 */ h=hcf(n1,n2); /* 调用求最大公约数函数调用求最大公约数函数 */ printf(greatest common divisor: %dn,h); l=lcd(n1,n2,h); /* 调用求最小公倍数函数调用求最小公倍数函数 */ printf(lease common multiple: %dn,l);/* 求两个数的最大公约数求两个数的最大公约数 */int hcf(int u,int v) int t; if(vu) t=u
64、; u=v; v=t; /* 交换两数,使交换两数,使u大大v小小 */ t=v; /* 最大公约数的最大值就是这两个数的最小值最大公约数的最大值就是这两个数的最小值 */ while(u%t!=0|v%t!=0) /* 同时能整除同时能整除u与与v的数就是最大公约数的数就是最大公约数 */ t-; return(t);/* 求两个数的最小公倍数,求两个数的最小公倍数,h为最大公约数为最大公约数 */int lcd(int u,int v,int h) return(u*v/h);2024/8/2056解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计解法二解
65、法二解法二解法二:辗转相除法辗转相除法辗转相除法辗转相除法使除数变为被除数,余数变为除数使除数变为被除数,余数变为除数uv交换交换u和和v,使大者为被除数使大者为被除数vTF除数除数a=u,被除数被除数b=vb/a的余数不为的余数不为0返回最大公约数返回最大公约数a2024/8/2057解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计解法二解法二解法二解法二:辗转相除法辗转相除法辗转相除法辗转相除法/*LI5_8_2.c*/#include #include int hcf(int u,int v);int lcd(int u,int v,int h);vo
66、id main() int n1,n2,h,l; clrscr(); scanf(%d,%d,&n1,&n2); h=hcf(n1,n2); printf(greatest common divisor: %dn,h); l=lcd(n1,n2,h); printf(lease common multiple: %dn,l);/* 求两个数的最大公约数求两个数的最大公约数 */int hcf(int u,int v) int t; if(vu) t=u; u=v; v=t; /* 交换两数,使交换两数,使u大大v小小 */ while(v!=0) /* 最后的余数为最后的余数为0时,结束循环时
67、,结束循环 */ t=u%v; u=v; v=t; /* 辗转相除法求最大公约数辗转相除法求最大公约数 */ return(u);/* 求两个数的最小公倍数,求两个数的最小公倍数,h为最大公约数为最大公约数 */int lcd(int u,int v,int h) return(u*v/h);2024/8/2058解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-105-10计算计算的前的前20项和。项和。 【分析分析】编写两个函数编写两个函数f1和和f2。f1用来计算每项分子的值,可以用用来计算每项分子的值,可以用static变量来存放上一次的值
68、,以便计算当前值;变量来存放上一次的值,以便计算当前值;f2用来计用来计算每项分母的值,可以使用递归调用方式求解。算每项分母的值,可以使用递归调用方式求解。2024/8/2059解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-105-10程序程序程序程序/*LI5_10.c*/#include #include float f1(int x);float f2(int n);void main() float exp=1.0; int x,n; clrscr(); printf(Input a number:); scanf(%d,&x); /*
69、 输入输入x的值的值 */ printf(x=%dn,x); exp=exp+f1(x); /* 计算计算ex的第一项值的第一项值 */ for(n=2;n=19;n+) exp=exp+f1(x)/f2(n); /* 计算计算ex的各项值并累加的各项值并累加 */ printf(The is exp(%d)=%8.4fn,x,exp);/* 定义计算分子定义计算分子xn的值的值 */float f1(int x) static float j=1.0; j=j*x; return(j);/* 定义计算分母定义计算分母n!的递归函数的递归函数 */float f2(int n) if(n=1)
70、 return(1.0); else return(n*f2(n-1);2024/8/2060解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-115-11输入年份并输出当年的日历输入年份并输出当年的日历输入年份并输出当年的日历输入年份并输出当年的日历【分析分析】在主函数中,首先需要执行输入年份的函数,再执行输出该年在主函数中,首先需要执行输入年份的函数,再执行输出该年份日历的函数。份日历的函数。在输出年份日历函数中,使用循环打印在输出年份日历函数中,使用循环打印12个月每个月的日历个月每个月的日历信息。而每个月的日历信息又要调用很多函数,如:每月
71、的天信息。而每个月的日历信息又要调用很多函数,如:每月的天数、每月第一天是星期几等函数。数、每月第一天是星期几等函数。本程序的关键在于:计算出每月的天数、确定每月的第一天是本程序的关键在于:计算出每月的天数、确定每月的第一天是星期几、缩排月历的第一行使得第一天出现在正确的位置上。星期几、缩排月历的第一行使得第一天出现在正确的位置上。程序以程序以1900年年1月月1日是星期一为参考点,从这天开始,按是日是星期一为参考点,从这天开始,按是否为闰年,每年加否为闰年,每年加365天或天或366天;对于当年的要处理的月份天;对于当年的要处理的月份之前的月,加上这个月的天数;用除以之前的月,加上这个月的天
72、数;用除以7取模计算取模计算1900年以年以后的某一天是星期几。后的某一天是星期几。 2024/8/2061解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-115-11程序与结果程序与结果程序与结果程序与结果例例5-11的程序详见教材。的程序详见教材。2024/8/2062解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-115-11程序说明程序说明程序说明程序说明本例所定义的本例所定义的char *monthname(int month)函数,表示其函数返回值为函数,表示其函数返回值为char *型
73、数据,型数据,它是字符指针数据,表示返回一个字符串。它是字符指针数据,表示返回一个字符串。这个知识点将在后续章节中介绍。这个知识点将在后续章节中介绍。2024/8/2063解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计例例例例5-115-11程序调用关系程序调用关系程序调用关系程序调用关系maininputyearinputyearprtcalendarprtcalendarprtmonthcalendarprtmonthcalendarmonthnamemonthnamemonthdaysmonthdaysfirstdayofmonthfirstdayo
74、fmonthprintspaceprintspaceisleapyearisleapyear调用关系调用关系2024/8/2064解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计思考题思考题思考题思考题5-65-6例例5-11中所要用到的年、月、日三个变量能不能作为一个整中所要用到的年、月、日三个变量能不能作为一个整体来考虑呢?一年体来考虑呢?一年12个月的天数又能不能用一个数据来表示呢个月的天数又能不能用一个数据来表示呢?这就是我们将在下一章要介绍的内容。?这就是我们将在下一章要介绍的内容。v年、月、日三个数据可以使用结构体来表示年、月、日三个数据可以使用
75、结构体来表示v一年一年12个月的天数可以使用数组来表示个月的天数可以使用数组来表示2024/8/2065解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计学习建议学习建议学习建议学习建议v学好程序设计语言的唯一途径是 上机练习v你的编程能力与你在计算机上调试程序投入的时间成正比2024/8/2066解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计课后作业课后作业课后作业课后作业v1阅读教材第阅读教材第5章章v2读程序写结果:习题读程序写结果:习题5.1、习题、习题5.2v3读程序写功能:习题读程序写功能:习题5.3、习题、习题5.4v4程序填空:习题程序填空:习题5.5、习题、习题5.6v5程序改错:习题程序改错:习题5.7、习题、习题5.8v6编写程序:习题编写程序:习题5.9习题习题5.172024/8/2067解析解析C程序设计(第程序设计(第2版)第版)第5章章 模块化程序设计模块化程序设计