收藏 分享(赏)

第13讲- 多函数程序设计-3.ppt

上传人:fmgc7290 文档编号:7288810 上传时间:2019-05-13 格式:PPT 页数:28 大小:205.50KB
下载 相关 举报
第13讲- 多函数程序设计-3.ppt_第1页
第1页 / 共28页
第13讲- 多函数程序设计-3.ppt_第2页
第2页 / 共28页
第13讲- 多函数程序设计-3.ppt_第3页
第3页 / 共28页
第13讲- 多函数程序设计-3.ppt_第4页
第4页 / 共28页
第13讲- 多函数程序设计-3.ppt_第5页
第5页 / 共28页
点击查看更多>>
资源描述

1、第13讲,多函数程序设计-3,2,上节重点 变量作用域 变量的存储类型 本节重点 嵌套调用 递归调用,3,函数设计的原则,函数的功能要单一,不要设计多用途的函数 函数的规模要小,尽量控制在50行代码以内 1986年IBM在OS/360的研究结果:大多数有错误的函数都大于500行 1991年对148,000行代码的研究表明:小于143行的函数比更长的函数更容易维护 参数和返回值的规则 参数要书写完整,不要省略 对函数的入口参数进行有效性检查 没有参数和返回值时,用void填充 每个函数只有一个入口和一个出口,尽量不使用全局变量 尽量少用静态局部变量,以避免函数具有“记忆”功能,4,例:求三个数最

2、大值最小值的差,定义函数分别求: 两个数的最大值 两个数的最小值 再在主函数中调用它们求三个数的最大值和最小值,再求差。,不要求三个数的最大值,因为相比之下,求两个数最大值这个函数在今后的复用率会更高。,5,程序,#include #include int Max(int a,int b); /函数声明 int Min(int a,int b); /函数声明 void main() int a,b,c,max,min; /定义printf(“请输入三个整数:“);scanf(“%d,%d.%d“, ,6,例5-5,求n! 1 n=1n*(n-1)! n1,double Fac(int n) i

3、f(n=1) return 1;else return n*Fac(n-1); ,写成函数?,7,例5程序,#include double Fac(int n) if(n=1) return 1;elsereturn n*Fac(n-1); void main() int n;printf(“please input a number:n“);scanf(“%d“, ,f(10) return 10*f(9 ); ,f(9) return 9*f(8 ); ,f(1) return 1; ,f(2) return 2*f(1); ,执行过程?,递归:函数嵌套调用自身,8,递归 迭代,doubl

4、e Fac(int n) if(n=1) return 1;elsereturn n*Fac(n-1); ,double Fac(int n) double fc=1;int i;for(i=1;i=n;i+)fc=fc*i;return fc; ,9,递归与迭代的比较,n! 1 n=1n*(n-1)! n1,n!=(1*2)*3)*n),10,什么问题可以用递归来解决?,问题具有如下特点: 问题较复杂,不易用迭代法直接求解 该问题可以分解成若干子问题,子问题除了规模较原问题小以外,其它均相同。 最终,总有一个问题不能再分解。,11,例5-4 求解Hanoi(汉诺)塔问题,古代有一个梵塔,塔内

5、有三个柱子A、B、C,僧侣们想把A拄子上的一摞盘子移动到C柱子上。最初A拄子上有大小不等的64个盘子,且小的在上,大的在下。在移动过程中,大盘子只能在下,小盘子只能在上,并且每次只能移动一个盘子,可以借助于B柱子。,12,问题分析,解决Hanoi(汉诺)塔问题的方法可以表述如下: 老和尚移动64个盘子的步骤 第1步,请第2个和尚将前63个盘子从A柱子移到B柱子; 第2步,自己将最下面的第64个盘子从A柱子移到C柱子; 第3步,再请第2个和尚将63个盘子从B柱子移到C柱子。 第2个和尚移动63个盘子的步骤 第1步,请第3个和尚将前62个盘子从A柱子移到C柱子; 第2步,自己将最下面的第63个盘子

6、从A柱子移到B柱子; 第3步,再请第3个和尚将62个盘子从C柱子移到B柱子。 依此类推,直到第63个和尚完成了2个盘子的移动,最后由第64个和尚完成1个盘子的移动。这个过程称之为“回推“过程。,每个人的工作是:移动n个盘子从A到B(借助C)的步骤 第1步,请别人将n-1个盘子从A柱子移到C柱子; 第2步,自己将最下面的第n个盘子从A柱子移到B柱子; 第3步,再请别人将n-1个盘子从C柱子移到B柱子。 一个特例:当n=1的时候,13,move函数,/* 定义函数:显示移动过程int no:表示第no个盘子char from:表示源柱子char to:表示目的柱子 */ void move(int

7、 no,char from,char to) printf(“Move %3dth disk:%c -%cn“,no,from,to); ,14,hanoi函数,/* 定义函数:借助by柱子将n个盘子从from柱子移动到to柱子int n:表示n个盘子 char from:表示源柱子char to:表示目的柱子,char by:表示要借助的柱子 */ void hanoi(int n,char from,char by,char to) if (n=1) move(n,from,to); else hanoi(n-1,from,to,by); move(n,from,to); hanoi(n-

8、1,by,from,to); ,15,#include /* 包含头文件 */ void move(int,char,char); /* 自定义函数的声明 */ void hanoi(int n,char,char,char); /* 自定义函数的声明 */ void main() /* 主函数,无参数,无返回值 */ int n; /* 定义整型变量n,存放盘子总数 */printf(“Input the number of diskes: “); /* 提示输入n的值 */scanf(“%d“, ,完整程序,16,运行输出:,Input the number of disks: 3 The

9、 step to moving 3 disks: Move 1: A B Move 2: A C Move 3: B C Move 4: A B Move 5: C A Move 6: C B Move 7: A B,17,语法:函数的递归调用,在调用一个函数的过程中又直接或间接地调用函数本身,f( ) f( ); ,f1( ) f2( ); ,f2( ) f1( ); ,特殊形式的函数嵌套,重点,直接递归,间接递归,18,练习3(例5-6):写递归函数计算fabonacci数列的第n项,19,练习3程序,#include long fib(int n); /* 自定义函数声明 */ void

10、 main() long s; /* 第 i 项斐波那契数列的值 */int i=0; /* 斐波那契数列某项的序号 */do s=fib(i); /* 求斐波那契数列第 i 项 */printf(“Fib(%d)=%ldn“,i,s); /* 显示斐波那契数列第 i 项的值 */printf(“Input Fibonacci Number,0 means exiting:“);scanf(“%d“, /* 求斐波那契数列的递归方式 */ ,20,带参数的宏定义,#define SQUARE(n) (n)*(n) void main() int i=1;for( ;i=10;i+)printf

11、(“%4d“, SQUARE(i) ); ,void main() int i=1;for( ;i=10;i+)printf(“%4d“, (i)*(i) ); ,编译前 替换为:,21,区别,(i)*(i),当函数功能非常简单时,可以用带参数的宏定义来实现。,22,涉及语法 -带参数的宏定义,一般格式:#define 宏名(参数表) 字符序列 功能:将程序中出现的前者置换为后者。其中宏名后面的括号里是参数,类似函数中形参表,只是此处的形参无类型说明。字符序列中应包含括号中所指定的参数,否则参数设置无意义。,23,应注意的问题,使用带参数的宏定义可以实现某些简单函数的功能(注意是某些,而不是全

12、部)。 定义时,宏名和参数表之间不能有空格。 对带参数的宏定义,字符序列及其字符序列中各个形参都应该用圆括号括起来。 例:#define SQUARE(n) (n)*(n),#define s (a,b,c) a*b*c main() printf(“%d“, s(3+5,5/2,2+3); ,3+5*5/2*2+3,#define f(x,y) (x)+(y) main() int a=4,b=3; printf(“%d“, f(a,b)*f(a,b) ); ,(a)+(b)*(a)+(b),(a)*(b)*(c),(a)+(b),24,函数相关知识小结,多函数程序设计 为什么定义函数?怎样

13、编写多函数的C程序 函数的定义、调用、声明格式 理解函数的调用过程(程序的执行过程) 什么情况下用递归?递归的解题思路是什么?递归的执行过程是什么?递归与递推有何区别? 变量的作用域和存储类型 如何分类?各具有什么特点?什么情况下用全局变量和static变量。 带参数的宏定义 用法,以及与函数的区别,25,作业2:,分别用递归法和迭代法求解(都要写成函数): S(x,n)=x1+x2+xn; 自学例题:求解Hanoi(汉诺)塔问题。关键是要搞清楚递归函数的写法(即如何将n的问题转化为n-1的问题),以及递归调用的过程(输入3试跟踪一下调用过程),26,作业2答案,问题的关键是如何将n的问题化解

14、为n-1的问题(即反方向求解问题)。 根据分析,写出如下的数学函数:,double S(float x, int n) if(n=1)return x;elsereturn S(x,n-1)+pow(x,n); /*若函数定义为float,会有类型不一致的警告*/,27,#include #include double S(float x, int n); void main() double x,s; int n;printf(“please input x,n:n“);scanf(“%lf,%d“, /*递归要通过函数的依次调用实现*/ ,习题5.12程序,#include #includ

15、e double S(float x, int n); void main() double x,s; int n;printf(“please input x,n:n“);scanf(“%lf,%d“, ,切忌: 将递归函数的内容写至主函数中; 将递归中的语句放至循环中; 在递归函数中写s(x,n)=S(x,n-1)+pow(x,n);,28,Hanoi(3,A,B,C) else hanoi(2,A,C,B); move(n,A,C); hanoi(2,B,A,C); ,Hanoi(2,A,C,B) else hanoi(1,A,B,C);move(n,A,B); hanoi(1,C,A,B); ,Hanoi(1,A,B,C) move(1,A,C); ,Hanoi(1,C,A,B) move(1,C,B); ,Hanoi(2,B,A,C) else hanoi(1,B,C,A); move(n,B,C);hanoi(1,A,B,C); ,Hanoi(1,B,C,A) move(1,B,A); ,Hanoi(1,A,B,C) move(1,A,C); ,作业:请大家用讲过的单步执行方法观察一下n为3的执行过程,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 中等教育 > 小学课件

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报