C语言之旅-函数递归

  说到递归这个词,听起来就比较模糊,不是十分好懂。那么今天就让我们看看函数递归到底是怎么回事吧!

  什么是递归及递归的限制条件

  首先我们先了解一下递归的具体意思吧,在C语言中递归就是函数自己调用自己。分开来看下,其中“递”是地推的意思,“归”是回归的意思。

  还是有点难以理解,那让我们来看下这个超简单的递归吧。

int main()

      printf("hehe\n");

      main();

      return 0;

   }

  在这个函数中main函数自己调用自己,实现不断打印hehe的效果,但过不了多久这个程序就会崩掉。进行调试后可发现会出现如下报错

51d2dc3772ea4bd59e091a7a8b3c9583.jpg

这个就是递归不当所产生的比较常见的错误,叫做栈溢出(每次函数调用都会占领栈区一块空间,经过多次递推而无回归会使栈的空间被占用完,而产生栈溢出的错误)。

  那么如何避免这个错误呢,这就涉及到递归的限制条件了

  • 递归要有一个限制条件,当达到这个条件时递归讲不再继续。
  • 每次递归后要更加接近这个递归条件

  递归举例

  上面大概就把递归介绍完了,那我们来举个例子看看吧。

  让我们用递归来进行顺序打印一个数的每一位吧。

  先来分析一下,如果是逆序打印1234这个数的话就会简单一些,让这个数字模10就可以拿到最后一位数,再把他除10再模10就可以拿到倒数第二位,那根据类似的原理我们可以把顺序打印理解为先顺序打印123在打印一个4,同理,顺序打印123也可以看做先顺序打印12在打印3,以此类推就可以顺序打印出1234。

  根据上面的分析可知,这个过程就是递归,而递归的限制条件就是这个数字为一位数,每次递归后通过将原数字一次次除10使递归接近限制条件,让我们来看下推演图更直观的理解一下这个过程吧。

7ed957f7cb774ea387625da9d17f637f.jpg

   理解了过程后就可以打出如下代码

void Print(int n)

{

   if(n>9)

   {

         Print(n/=10);

     }

   else

         printf("%d",n%10);

  }

int  main()

{

   int n=0;

   scanf("%d",&n);

   Print(n);

   return 0;

  }

  递归的缺陷

  让我们来用实例来说明这件事吧,用递归写一个求斐波那契数的代码。斐波那契数运算表示如下

51e7ad7ddae2400d855f1dc11fbbd290.jpg

   根据提示,我们可以很快写出递归的代码

int Fib(int n)
{
   if(n<=2)
        return 1;
   else
        return Fib(n-1)+Fib(n-2);

int main()
{
    int n = 0;

    scanf("%d", &n);

    int ret = Fib(n);
    printf("%d\n", ret); 
    return 0;

   但如果在这里输入50,那么你会发现计算机在不断计算但不返回结果,这是为什么呢?

  因为根据递归所以在计算第50个斐波那契数时会算第49和48个,在计算第49个时,有需要计算第48和47个…这样就会产生很多次循环计算,是结果返回的很慢。

a6ed1d0cea2b4ab7b0296b4a285da855.jpg

  所以递归固然写代码很简单,但他有一定的缺陷,在计算斐波那契数时如使用递归则会造成多次重复运算,减缓计算速度,从而不如用循环简便。并且如果递归层次太深也会导致栈溢出的现象。递归虽好,但不要迷恋哦。

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值