任务描述
计算机编译或运行时,使用某个函数来完成相关功能。对无参函数调用时则无实际参数表。对有参函数调用时实际参数表中的参数可以是常数、变量或其他构造类型数据及表达式。各实参之间用逗号分隔。除了项目1 中3 种基本的函数调用形式以外,还有其他的函数调用形式。本项目主要目的是掌握函数的嵌套调用和递归调用。
知识学习
(1)函数的嵌套调用
C语言中不允许作嵌套的函数定义。因此各函数之间是平行的,不存在上一级函数和下一级函数的问题。但是C语言允许在一个函数的定义中出现对另一个函数的调用。这样就出现了函数的嵌套调用,即在被调函数中又调用其他函数。这与其他语言的子程序嵌套的情形是类似的。简单归纳:嵌套调用就是某个函数调用另外一个函数。例如下面程序就是在主函数中调用自定义函数:
y=f(n);
例5.10 任意输入一个正整数给n,求n 的阶乘。要求将求解某个正整数的阶乘功能用自定义函数来实现,运行结果如图5.9所示。
图5.9 程序运行结果
说明:该程序从main 函数开始执行,当输入n 的值之后,调用f 函数来实现求解n 的阶乘,这就是函数的嵌套调用。包括在main 函数中还调用了printf 和scanf 函数实现输入与输出功能,这也是函数的嵌套调用。在程序设计中,函数的嵌套调用是最常见的一种。
(2)函数的递归调用
函数的递归调用是一种特殊的嵌套调用,是某个函数调用自己或者是调用其他函数后再次调用自己的函数,只要函数之间互相调用能产生循环的则一定是递归调用,递归调用是一种解决方案,另外一种是逻辑思想,将一个大工作分为逐渐减小的小工作,比如说一个和尚要搬50 块石头,他想,只要先搬走49 块,那剩下的1 块就能搬完了,然后再考虑那49 块,只要先搬走48 块,那剩下的一块就能搬完了,递归是一种思想,只不过在程序中,是依靠函数嵌套这个特性来实现的。简单归纳:函数的递归调用就是调用一个函数过程中又调用该函数本身。
例5.11 任意输入一个正整数给n,求n 的阶乘。要求将求解某个正整数的阶乘功能必须使用函数的递归调用实现,运行结果如图5.10所示。
图5.10 程序运行结果
分析:
程序:
说明:通过程序的分析大家可以发现当计算5 的阶乘时,f 函数前后被调用了5 次。第1次是主函数中调用f 函数计算f(5)的值,当执行f 函数的时候根据提交执行的是5*f(4);第2 次调用f 函数计算4 的阶乘,当执行f 函数的时候根据提交执行的是4*f(3);第3 次调用f函数计算3 的阶乘,当执行f 函数的时候根据提交执行的是3*f(2);第4 次调用f 函数计算2的阶乘,当执行f 函数的时候根据提交执行的是2*f(1);第2 次调用f 函数计算1 的阶乘,当执行f 函数的时候根据提交执行的是1,到此截止,递推结束。然后在先后调用5 次return 语句实现递归,将f(1)的结果1 返回给2*f(1),从而计算出f(2)的结果;接着将f(2)的结果2返回给3*f(2),从而计算出f(3)的结果;接着将f(3)的结果6 返回给4*f(3),从而计算出f(4)的结果;接着将f(4)的结果24 返回给5*f(4),从而计算出f(5)的结果;将f(5)的结果返回给主函数中y=f(n)处;最后输出结果。把上述利用文字对递归的解释过程描述为如图5.11所示。
图5.11 利用递归函数求5 的阶乘的计算过程
例5.12 Hanoi 塔问题。一块板上有3 根针,A、B、C。A 针上套有64 个大小不等的圆盘,大的在下,小的在上,如图5.12所示。要把这64 个圆盘从A 针移动C 针上,每次只能移动一个圆盘,移动可以借助B 针进行。但在任何时候,任何针上的圆盘都必须保持大盘在下,小盘在上。求移动的步骤。
(www.xing528.com)
图5.12 Hanoi 塔示意图
分析:
①如果有1 个圆盘从A 到C,1 步完成。
②如果有2 个圆盘从A 到C,将分3 步完成:A→B,A→C,B→C。那么任意2 个圆盘从其中一个起始针到终止针都应该是3 步完成。
③如果有3 个圆盘从A 到C,使用递归思想,利用2 个圆盘的移动方法帮助完成。步骤如下:
第1 步:将顶端的前2 个圆盘从A 到B;
第2 步:再将最底端的1 个圆盘从A 到C;
第3 步:最后将原顶部2 个圆盘从B 到C。
注意,其中第1 步和第3 步都要利用2 个圆盘的移动方法帮助完成。
换成函数形式来表达,3 表示3 个圆盘,A 表示起始针,B 表示借助针,C 表示目标针。
Hanoi(3,A,B,C)应该分解为3 步,如图5.13所示。
图5.13 以3 个圆盘为例从A 到C 的移动过程分析
归纳总结:
程序运行结果如图5.14所示。
图5.14 程序运行结果
任务总结
本任务主要学习函数的递归调用,所谓递归调用就是在调用一个函数的过程中又调用该函数本身。通过上述实例分析和演示,总结归纳出函数的递归调用在程序设计中必须具备的2 个要素(缺一不可):
①递归算法:
②终结条件:
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。