当前位置:   article > 正文

C语言函数递归调用

c语言函数递归调用

1、函数递归调用的定义

递归函数定义:一个函数在 自己的函数体内 调用自己;执行递归函数将反复调用其自身,每调用一次就有一个新层

  1. #include<stdio.h>
  2. // 函数声明
  3. void diguifunc();
  4. int main() //主函数
  5. {
  6. diguifunc(); //运行后程序会崩溃,资源耗尽了
  7. }
  8. // 递归函数的定义
  9. void diguifunc()
  10. {
  11. int tempvar1 = 150; //局部变量:在函数内部定义的变量,当函数整个执行完毕后,局部变量所占的内存会被系统自动回收,回收后该局部变量就不可以再使用了。
  12. printf("diguifunc函数执行-----\n");
  13. diguifunc();
  14. }
  15. // 调用栈(一块系统分配给咱们这个程序有特殊用途的内存):就是把形式参数,函数调用关系,局部变量等进行保存在栈里面。
  16. 这段内存是有限的,如果一旦超过这个内存大小,就会出现崩溃现象。

函数递归调用运行图:

2、递归调用的出口

因为上面这种递归调用会产生死循环,所以这种自己调用自己的方式必须要有一个出口,这个出口也叫做递归结束条件,从而能够让这种函数调用结束。

范例:计算5的阶乘,其实就是计算 1*2*3*4*5,

我们并不知道5的阶乘是多少,但是我们知道一点,4的阶乘 * 5他就等于5的阶乘。

我们并不知道4的阶乘是多少,但是我们知道一点,3的阶乘 * 4他就等于4的阶乘。

我们并不知道3的阶乘是多少,但是我们知道一点,2的阶乘 * 3他就等于3的阶乘。

所以递归调用的出口肯定是在1的阶乘,因为1的阶乘是1,可以作为出口,我们能够求出2的阶乘,也就是1*2;以此类推瑞。

  1. #include<stdio.h>
  2. // 函数声明
  3. int dg_jiecheng(int n);
  4. int main() //主函数
  5. {
  6. int result = dg_jiecheng(5);
  7. printf("result=%d\n",result); // 结果为120
  8. }
  9. // 函数定义
  10. int dg_jiecheng(int n)
  11. {
  12. int result; // 局部变量,保存阶乘结果
  13. if(n==1) // 1的阶乘就是1
  14. {
  15. return 1; // 这里就是该递归调用的出口
  16. }
  17. else
  18. {
  19. // 第一次是 result = dg_jiecheng(4)*5,然后进入到了 dg_jiecheng(4),这行代码就被暂存了;
  20. 第二次是 result = dg_jiecheng(3)*4,然后进入到了 dg_jiecheng(3),这行代码就被暂存了;
  21. 第三次是 result = dg_jiecheng(2)*3,然后进入到了 dg_jiecheng(2),这行代码就被暂存了;
  22. 第四次是 result = dg_jiecheng(1)*2,然后进入到了 dg_jiecheng(1),这行代码就被暂存了;
  23. 此时,dg_jiecheng(1)的出口条件成立了,终于,能够执行return 1,这可是 return 语句第一次捞着执行。
  24. 第一次:return 1,返回的是1,返回到dg_jiecheng(2)这里:
  25. return =1*2 并且也执行return result;,返回1*2=2
  26. 返回到dg_jiecheng(3)这里:
  27. return =2 并且也执行return result;,返回2*3=6
  28. 返回到dg_jiecheng(4)这里:
  29. return =6 并且也执行return result;,返回6*4=24
  30. 返回到dg_jiecheng(5)这里:
  31. return =24 并且也执行return result;,返回24*5=120
  32. result = dg_jiecheng(n-1)* n;
  33. }
  34. return result;
  35. }

3、递归的优缺点

优点:

        代码少,代码看起来简洁,精妙。

缺点:

        虽然代码简洁,精妙,但是不好理解。

         如果调用的层次太深,调用栈(内存),可能会溢出,如果真出现这种情况,那么说明不能用递归解决该问题。

        效率和性能都不高,这深层次的调用,要保存的东西很多,所以效率和性能肯定高不起来。有些问题用不用递归都行,有些问题可能必须用递归解决。汉诺塔

         递归函数的直接和间接调用:

递归函数的直接调用:调用递归函数f的过程中,f函数有调用自己,这就是直接调用。

递归函数的间接调用:调用函数f1的过程中要调用f2函数,然后f2函数又调用f1函数,这就是间接调用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/442551
推荐阅读
相关标签
  

闽ICP备14008679号