分享

C语言递归的理解

 围巢1991 2016-04-11
  今天来写写对递归的理解。

  关于递归,百度搜索给出了很多答案。无非就是递归是一种思想,其代码量少,但执行效率不高等等。

  递归其实分为"递"和"归"。递就是传递,就是将一个大问题细化成更小的问题,直到不能再小,那么这时候函数就得到一个最终的值,而这个值是我们可以知道的。这时候就执行"归",函数带着那个最终的值逐级返回,返回直到第一次调用函数自身时,就终止了"归",最终的结果返回给调用函数。

  其实递归的难点有二:

  1:递归就是函数直接或间接调用自身,那么它是怎么执行的呢?

  2:递归什么时候该终止呢?它又是怎么返回的?

  只要明白了这两点,理解递归就比较容易了。首先,我们要清楚函数调用的过程与返回。

  用个简单的例子来说明一下:

  int s(int x);

  main()

  {

  int a=1;

  s(a);

  return 0;

  }

  int s(int x)

  {

  int y=2;

  return x+y;

  }

  在这个程序里,main是主函数,s是自定义函数。在main里,调用了s函数。我们称main是调用函数,s是被调用函数。程序执行到s(a),调用了s函数,给这个函数传了个参数a。

  (注:这里的参数a是实参,s里的x是形参。)

  s函数被定义为了int型,它的返回值同样也是int型的。这点一定要记住。程序执行到s(a),给s传了个参数,然后会留下一个返回main函数的入口地址,就转到s函数里去执行了。(main函数此时则是等待s函数执行完毕)。那么就会执行x+y,得到结果3,然后带着结果3,根据之前留下的返回main函数的入口地址返回到main函数中,程序控制权转交给main,main则继续往下执行后续语句。

  当函数调用发生时,程序会像画面定格一样,保存当前场景。然后当被调用函数执行完毕后,会带着返回值返回到调用函数中。这就是函数调用大概的过程。

  明白了函数调用的过程,下面就以那个阶乘的递归程序来详细了解一下递归的工作过程。

  #include

  long fact(int );

  int main()

  {

  printf("结果是:%ld",fact(4));

  return 0;

  }

  long fact(int n)

  {

  long f;

  if (n>1)

  f=fact(n-1)*n;

  else

  f=1;

  return f;

  }

  在main里传了个4给fact函数,然后使用fact的返回值输出。

  程序转到fact函数里执行。判断4大于1,执行f=fact(n-1)*n。关键之处来了,这句又调用了fact这个函数,我们之前说过,调用一个函数,程序会保存当前场景,留下一个返回调用函数的入口地址,然后转到被调用函数继续执行。所以这里,程序会保存当前状态,留下一个返回到这里的入口地址,然后使用参数n-1,也就是3,转到被调用函数fact继续执行!而不是执行*n!然后程序继续判断3大于1,继续调用fact…以此类推。最后一直到n的值为1时,因为1不大于1,所以会执行else语句,直接给f赋为1。然后程序执行return f,f的值也就是1,返回。然后程序控制权转交到最后一次的调用函数,又会执行一次那个语句。也就是会返回到n-1=1时的那次。然后执行*n,此时n是2,1*2得2。然后带着这个结果继续返回调用函数。然后,继续逐级返回。每次返回,都是带着被调用函数的返回值。

  最后,递归结束,控制权返回到最初的fact,得到结果24。函数返回到main,继续执行,输出fact最终的返回值24。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多