| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 909 人关注过本帖
标题:我又回来了这次是阶乘的一个函数的问题。。
只看楼主 加入收藏
海猫猫
Rank: 2
等 级:论坛游民
帖 子:7
专家分:15
注 册:2016-9-4
结帖率:100%
收藏
已结贴  问题点数:18 回复次数:6 
我又回来了这次是阶乘的一个函数的问题。。
核心的代码为:
printf("loop: %d factorial = %d\n",num,fact(num));
printf("recursion: %d factorial = %ld\n",num,rfact(num));
用循环的阶乘函数为
long fact(int n)
{
 long ans ;
  for (ans = 1; n > 1;n++)
     ans *= n;

  return ans;
}
用递归的阶乘函数为
long rfact(int n)
{
  long ans;
   
  if(n > 0)
      ans = n * rfact(n-1);
    esle
       ans = 1;
     return ans;
}
问题1   关于用递归的函数我搞不清楚他的流程。。我的理解是这样的:(假设输入的是一个5
5大于一个0,成立,进入ans = n * rfact(n-1) n此时变成了4,3,2,1,0 结果为 ans==120;但是这个自己调用自己的函数什么时候会退出?一共是调用5次吗?
如果可以的话希望可以给我讲讲这个函数的具体流程,这个语句结束了到哪里之类的。

问题2 关于esle,当n减到0时难道不是要执行这个语句吗?那么ans的返回值不会变成1吗?为什么还是120呢?(刚刚我突然想到,每级递归变量都属于本级递归私有,于是第五次递归的n是0,ans变成1。但是返回值是返回最开始的ans?。。。
以上,提前谢谢各位了。。对递归了解不够深,问题问的也模模糊糊的。。。抱歉



搜索更多相关主题的帖子: recursion return 
2016-12-07 04:49
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:6 
递归用栈,后进先出。
n
0,   1 rfact(0)
1,   1 rfact(1)->1*rfact(0)->1*1
2,   2 rfact(2)->2*rfact(1)->2*1*rfact(0)->2*1*1
3,   6 rfact(3)->3*rfact(2)->3*2*rfact(1)->3*2*1*rfact(0)->3*2*1*1
4,  24 rfact(4)->4*rfact(3)->4*3*rfact(2)->4*3*2*rfact(1)->4*3*2*1*rfact(0)->4*3*2*1*1
5, 120 rfact(5)->5*rfact(4)->5*4*rfact(3)->5*4*3*rfact(2)->5*4*3*2*rfact(1)->5*4*3*2*1*rfact(0)->5*4*3*2*1*1
2016-12-07 05:40
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
这样看看:
#include<stdio.h>

long rfact(int n)
{
    long ans;

    if(n > 0)
        ans = n * rfact(n-1);
    else
        ans = 1;
        
    printf("%hd\n", ans);  
      
    return ans;
}

int main()
{
    rfact(5);
    return 0;
}
2016-12-07 05:42
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
个人感觉,能不用递归就不用。
看似简洁,但不好阅读,效率未必高,栈空间也很有限。

[此贴子已经被作者于2016-12-7 07:16编辑过]

2016-12-07 05:45
海猫猫
Rank: 2
等 级:论坛游民
帖 子:7
专家分:15
注 册:2016-9-4
收藏
得分:0 
回复 4楼 吹水佬
原来还有一个重要的知识点叫做"栈"!我只是在书上看过他的基础的概念,但是目前还没有学到这。。。。那么前辈,问题2里我那样理解是正确的吗?
2016-12-07 11:17
yangfrancis
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:贵宾
威 望:141
帖 子:1510
专家分:7661
注 册:2014-5-19
收藏
得分:6 
当实参减到1的时候当然返回1了,但只是返回给它的调用单位,不是返回给main函数,调用它的是n*rfact(n-1);也就是2*rfact(2-1);于是得到2*1,这个返回值2又会返回给rfact(2)的调用,这样一样返回到rfact(5)的调用才会返给main
2016-12-07 13:08
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:6 
可以这样理解递归函数执行流程:当碰到递数点时就暂停该函数栈的处理,另外开一个新的栈来从头开始执行递归函数。
调用递归时仅保留上次递归的函数地址和形参(值得注意的是,每次递归,函数的地址值是不同的)
递归时上次函数用到的栈空间没有释放,各个函数里面调用的值会被保留。
递归函数遇到return或者执行到末尾时执行地址将会调用上一次递归函数的地址值,就是说,和普通函数一样,继续执行函数下面的内容,返回时该次递归所用到的栈空间的动态变量会被释放。

以下的程序代码以及数据输出可以帮助理解递归流程

程序代码:
#include<stdio.h>
#include<stdlib.h>
int fun(int x,int n)
{
    static a=1;

    a++;
    x+=a;

    printf("a=%d x=%d n=%d\n",a,x,n);

    if (n<3)
        fun(x,n+1);

     printf("a=%d x=%d n=%d\n",a,x,n);

     return x;
}
int main()
{
    printf("----x=%d\n",fun(1,0));

    return 0;
}


图片附件: 游客没有浏览图片的权限,请 登录注册


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2016-12-07 18:33
快速回复:我又回来了这次是阶乘的一个函数的问题。。
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.035816 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved