
在函数主体中调用自身的函数称为递归调用,这种函数称为递归函数. 执行递归函数将反复调用自身,并在每次调用时进入一个新层. 当执行最里面的函数时,它将从内到外逐层退出.
递归函数不是C语言的专利. Java,C#,JavaScript,PHP等其他编程语言也支持递归函数.
让我们以查找阶乘为例,看看递归函数的工作原理. 阶乘n的计算公式!如下:
根据公式编写以下代码:
//求n的阶乘long factorial(int n) {if (n == 0 || n == 1) {return 1;}else {return factorial(n - 1) * n; // 递归调用}}int main() {int a;printf("Input a number: ");scanf("%d", &a);printf("Factorial(%d) = %ld\n", a, factorial(a));return 0;}
运行结果:
输入数字: 5↙
Factorial(5)= 120
factorial()是典型的递归函数. 调用factorial()之后,它将进入函数主体. 该函数仅在n == 0或n == 1时结束,否则它将继续调用自身.
由于每个调用的实际参数为n-1,即n-1的值分配给形式参数n,因此每个递归实际参数的值都将减少1,直到最终值n n-1为1. 如果再次进行递归调用,则形式参数n的值也为1,则递归终止递归 2次调用,它将逐层退出.
要了解递归函数,关键是要了解它如何逐层进入以及如何逐层退出. 让我们拿5!作为解释的例子.
1)查找5 !,即调用factorial(5). 当输入factorial()的主体时,由于形式参数n的值为5,不等于0或1,因此执行factorial(n-1)* n,即factorial(4)* 5为被执行. 为了获得该表达式的结果,必须首先调用factorial(4),并且必须暂停其他操作. 换句话说,在获得阶乘(4)的结果之前,无法执行其他任何操作. 这是第一次递归.
2)调用factorial(4)时,实际参数为4,形式参数n为4,不等于0或1,它将继续执行factorial(n-1)* n ,即执行factorial(3)*4. 为了找到该表达式的结果,必须首先调用factorial(3). 这是第二次递归.
3)以此类推,在四个递归调用之后,实际参数值为1,并且将调用factorial(1). 此时,您可以直接获取常量1的值并返回结果. 无需再次调用factorial()函数,并且递归结束.

下表列出了需要计算的实际参数/形式参数调用表单的进程级别/层号以及需要等待的结果
1
n = 5
阶乘(5)
阶乘(4)* 5
阶乘(4)的结果
2
n = 4
阶乘(4)
阶乘(3)* 4
阶乘(3)的结果
3
n = 3
阶乘(3)
阶乘(2)* 3

阶乘(2)的结果
4
n = 2
阶乘(2)
阶乘(1)* 2
阶乘(1)的结果
5
n = 1
阶乘(1)
1
没有
当递归进入最内层时,递归结束,并开始逐层退出,即逐层执行return语句.
1)当n的值为1时,到达最内层. 这时,返回结果为1,即factorial(1)的结果为1.
2)使用factorial(1)的结果,您可以返回到上一级来计算factorial(1)* 2的值. 此时获得的值为2,并且返回的结果也为2 ,即factorial(2)的结果为2.
3)以此类推,当您获得阶乘(4)调用的结果时,可以返回顶层. 计算后,阶乘(4)的结果为24,则表达式阶乘(4)* 5的结果为120,此时返回的结果也为120,即调用阶乘(5)的结果)是120,所以值5!已获得.

下表列出了从表达式的内部递归获得的递归结果,这些递归结果需要按出口的过程级别/层号调用形式逐步进行计算
(内部函数的返回值)表达式值
(当前通话的结果)
5
阶乘(1)
1
没有
1
4
阶乘(2)
阶乘(1)* 2
阶乘(1)的返回值为1
2
3
阶乘(3)

阶乘(2)* 3
阶乘(2)的返回值为2
6
2
阶乘(4)
阶乘(3)* 4
阶乘(3)的返回值为6
24
1
阶乘(5)
阶乘(4)* 5
阶乘(4)的返回值为24
120
到目前为止,我们已经对递归函数factorial()的进入和退出过程进行了深入的解释,并向每个人展示了看似复杂的调用详细信息. 即使您是初学者递归 2次调用,我相信您也可以解决这个谜.
每个递归函数应该只进行有限数量的递归调用,否则它将进入死胡同并且永不退出. 这样的程序毫无意义.
要使递归函数逐层进入然后逐层退出,需要解决两个问题:
factorial()是递归尾递归的最简单形式,也就是说,递归调用位于函数主体的末尾. 除了尾部递归外,还有两种更多的脑燃烧形式的递归,即中间递归和多层递归:
递归函数只是一种解决问题的技术. 像其他技术一样,它也有一些缺陷. 特别是: 递归函数具有非常大的时间和内存开销,在极端情况下可能导致程序崩溃.
我们将在接下来的三门课程中解释这些高级内容:
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-287748-1.html
草狗一定佩服你