7.3.2 递归调用的出口

这里用一个范例来阐述递归调用的出口。范例如下:计算5的阶乘,也就是计算1*2*3*4*5的结果值,这里通过计算5的阶乘,看一看递归调用的出口代码怎样写,看一看怎样才能结束函数的递归调用。

首先分析这个题目怎样计算,有人说用循环就可以计算。是的,循环可以计算,但现在是要用递归调用把它演绎出来,所以要采用递归的方法来解决这个问题。那怎样计算5的阶乘呢?分析一下:

(1)不知道5的阶乘是多少,但知道:4的阶乘*5就等于5的阶乘。

(2)不知道4的阶乘是多少,但知道:3的阶乘*4就等于4的阶乘。

(3)不知道3的阶乘是多少,但知道:2的阶乘*3就等于3的阶乘。

(4)不知道2的阶乘是多少,但知道:1的阶乘*2就等于2的阶乘。

(5)根据数学知识,可以知道1的阶乘就是1。

根据上面这些说明,可以看到,如果要用递归解决求5的阶乘的结果问题,那么这个递归调用的出口在哪里呢?没错,这个递归调用的出口就在1的阶乘这里。因为:

(1)1的阶乘是1,可以作为出口,能够求出2的阶乘,也就是1*2。

(2)2的阶乘知道了,就能够求出3的阶乘,也就是2的阶乘*3。

(3)3的阶乘知道了,就能够求出4的阶乘,也就是3的阶乘*4。

(4)4的阶乘知道了,就能够求出5的阶乘,也就是4的阶乘*5。

最后,就得到了5的阶乘的结果,5的阶乘的结果是120,那么代码是如何写的呢?重点看看这个递归函数怎样写,代码如下:

在main函数中,可以调用该函数计算5的阶乘。调用代码如下:

尽管递归函数dg_jiecheng的代码行数不多,上面也分析了不少理论知识,但会发现这些代码仍然有些难懂,可以通过设置断点逐行跟踪调试的方式帮助自己理解,加断点逐行调试的方法,是理解任何复杂问题的最好手段。这里不妨设置断点跟踪并分析一下程序的执行。下面这些分析的描述文字读者能看懂就看,看不懂可以先不理会,根据自己的思路来分析和理解递归调用问题即可:

其实,就算用跟踪的方法,上面这段程序也不好理解,只能凑合着理解了,可能随着后期读者逐步对递归函数写法的熟练,慢慢就会理解了。上面就演示了递归函数调用的出口,出口必须有,否则就会陷入递归调用死循环,导致系统资源耗尽而使程序运行崩溃或者异常退出。

关于递归调用的例子还有不少,但这里并不准备多讲,因为讲太多反而会造成理解负担。如果读者有兴趣,可以在网上找一些递归调用的范例研究,这样的范例很多。