深度讲解一个n的阶乘递归注意事项

递归调用要注意的一些问题,以及递归过程中的存储问题,下面将会通过例子逐层分析。

先给出源代码

#include<stdio.h>
int test(int n);//递归调用n的阶乘  
int test(int n){
    int  f=0;
    if (n>0)
    {
    f=n*test(n-1);
    }else{      //好好想想这里为什么要写else。
        f=1;
    }
    return f;
}
int main(){
    int n;
    int result;
    scanf("%d",&n); 
    result=test(n);
    printf("restlt:%d",result);
    return 0;
}

1.如上图所示,如果我们在test函数中,没有编写else条件,结果会是什么呢? 修改如下:

int test(int n){
    int  f=0;
    if (n>0)
    {
    f=n*test(n-1);
    }
    return f;
}

结果:在这里插入图片描述
为什么会出现这种问题?
首先,我们来做一个小小的测试:(添加一个输出语句,来验证过程

int test(int n){
    int  f=0;
    if (n>0)
    {
    f=n*test(n-1);
    }
    printf("f:%d",f);//新添加的
    
    return f;
}

添加prinf的目的是检查每次test迭代时候的f值。
结果如下:
在这里插入图片描述
问题1:为什么会出现4次迭代?
问题2:为什么每次迭代值为0?
问题3:如果改变int f,可以解决问题吗?
下面我们带着这3个问题来验证我们的操作.

问题分析解决:

我们要知道,递归实际上就是一个进出栈的问题,具有先进后出的特性。
我们借助这个知识,来分析。

假如我们输入3,他首先会调用test(),然后进入test函数执行操作,在test内部执行部分后会重新遇到test(),这就是一个递归过程。

首先,执行n=3,符合判断条件,执行f=3 * test(n-1),压入栈底,然后进入test(n-1)中,同样的顺序判断符合判断条件,执行到f=2 * test(n-1),然后压入栈中,同样的顺序,再判断,执行f=1 * test(n-1),进入test(n-1),注意,此时不再满足条件,于是执行return f 操作,记住,我们每次递归时初始值都是 int f=0,也就是最后依次压栈操作,return f 这个f等于0,所以我们上一张图打印的第一个f结果就是0,然后第二个结果 f=1 * test(n-1),此时等于f=1*0 ,所以也是0,上面都是这样,所以全都是0。也就是说我们之所以为0,是被int f=0所干扰。
那有些人又有问题,那直接赋值1就可以啊,那样就每不需要给赋else值了,对,这个当然可以。
那有的人又问了,那什么值都不赋,可以吗?也不加else。 这里当然不可以了,如果不给赋值,进入到最后一个压栈环节,我们并没有给int f赋值,系统又要return f,造成了一个结果,就是值不确定。做一个测试来观看。

int test(int n){
    int  f;
    if (n>0)
    {
    f=n*test(n-1);
    }
    
    printf("f:%d\n",f);
    
    return f;
}

在这里插入图片描述
为什么会出现这种情况?
函数里面声明的变量如果没有特别说明,都是局部变量,我们知道,局部变量有一个特别之处,就是局部变量不自动初始化,也就是说,这里系统给我们随机赋值了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

于弋gg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值