首页 > 编程笔记

C语言递归函数(附带示例)

如果在调用一个函数的过程中,又直接或者间接地调用了该函数本身,这种形式称为函数的递归调用,这个函数就称为递归函数。递归函数分为直接递归和间接递归两种。C语言的特点之一就在于允许函数的递归调用。

直接递归就是函数在处理过程中又直接调用了自己。例如:

int func(int a)
{
   int b,c;
   …
   c=func(b);
   …
}

其执行过程如图所示。

如果 func1() 函数调用 func2() 函数,而 func2() 函数反过来又调用 func1() 函数,就称为间接递归。例如:


其执行过程如图所示。

注意:这两种递归都无法终止自身的调用。因此在递归调用中,应该含有某种控制递归调用结束的条件,使递归调用是有限的,可终止的。例如可以用if语句来控制只有在某一条件成立时才继续执行递归调用,否则不再继续。

示例1

用递归方法求n!(n为≥1的正整数)。代码如下:
#include<stdio.h>
long fac(int n)   /*定义求阶乘的函数fac()*/
{
   long m;
   if(n==1)
      m=1;
   else
      m=fac(n-1)* n;  /*在函数的定义中又调用了自己*/
   return m;
}
main()
{   int n; float y;
    printf("input the value of n.\n");
    scanf("%d",&n);
    printf("%d!=%ld\n",n,fac(n));    /*输出n!*/
}
运行结果:

input the value of n.
6
6!=720

上面代码中采用递归法求解阶乘,就是 5!=4!*5,4!=3!*4,…,1!=1。可以用下面的递归公式表示。

可以看出,当 n>1 时,求 n 的阶乘公式是一样的,因此可以用一个函数来表示上述关系,即 fac() 函数。

main() 函数中只调用了一次 fac() 函数,整个问题的求解全靠一个 fac(n) 函数调用来解决。如果 n 值为 5,整个函数的调用过程如下图所示。


从图中可以看出,fac() 函数共被调用了 5 次,即 fac(5)、fac(4)、fac(3)、fac(2)、fac(1)。其中,fac(5) 是 main() 函数调用的,其余 4 次是在 fac() 函数中进行的递归调用。

在某一次的 fac() 函数的调用中,并不会立刻得到 fac(n) 的值,而是一次次地进行递归调用,直到 fac(1) 时才得到一个确定的值,然后再递推出 fac(2)、ac(3)、fac(4)、fac(5)。

在许多情况下,采用递归调用形式可以使程序变得简洁,增加可读性。但很多问题既可以用递归算法解决,也可以用迭代算法或其他算法解决,而后者计算的效率往往更高,更容易理解。如【示例1】代码也可以用 for 循环来实现。

示例2

用循环实现【示例1】。代码如下:
#include<stdio.h>
long fac(int n)
{   int i;long m=1;
   for(i=1;i<=n;i++)
   {
      m=m*i;
   }
   return m;
}
main()
{  int n;
   float y;
   printf("input the value of n.\n");
   scanf("%d",&n);
   printf("%d!=%ld",n,fac(n));
}

归纳总结

递归作为一种算法,在程序设计语言中被广泛应用,它通常把一个大型的复杂问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序代码就可以描述出解题过程所需要的多次重复计算,大大减少了程序的代码量。用递归思想写出来的程序往往十分简洁。

递归的缺点:递归算法的运行效率较低。在递归调用的过程中,系统为每一层的返回点、局部量等开辟了栈来存储,系统开销较大。递归次数过多,容易造成栈溢出等问题。

更多关于递归的示例请转到:

优秀文章