You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

递归是反向执行的?为何该C语言程序能按顺序输出结果?

递归执行顺序的困惑

我一直对递归存在困惑。我理解使用递归时本质上会创建栈帧,待所有栈帧创建完成后,递归会按反向顺序执行并输出结果。我尝试理解如下C语言程序:

#include<stdio.h>

//function declaration
int RecursvFcnTogetPrcntge();

float Var;
unsigned int count=1;
float Prcntge;

int main()
{

    printf("\nEnter a value to split in percentage: ");
    scanf("%f",&Var);

    Var=Var/100;
    RecursvFcnTogetPrcntge();


    return 0;
}

int RecursvFcnTogetPrcntge()
{

    if(count==3)
    {
        return 1;
    }

    Prcntge=Var*count;
    printf("\n%3d Percent = %.02f",count, Prcntge);
    count++;
    RecursvFcnTogetPrcntge();
    return 0;
}

我认为count等于3时会创建4个栈帧:1个main函数的,2个非if分支的,1个count==3的分支的。当进入count=3的栈帧后会返回1,随后回到count=2的栈帧执行打印,再依次回到count=1的栈帧,因此预期输出是:

2 Percent = 0.14
1 Percent = 0.07

但实际输出却是:

1 Percent = 0.07
2 Percent = 0.14

既然递归是反向执行的,为何该程序会按顺序调用并输出?我对递归的理解可能有误,希望得到帮助。


问题核心:误解了递归中代码的执行时机

递归的栈帧确实是先依次创建(调用阶段),然后依次返回(回溯阶段),但关键是:你的printf语句是在递归调用之前执行的,不是在递归调用返回之后。

我们一步步拆解程序的执行流程:

  1. main函数调用RecursvFcnTogetPrcntge(),此时count=1:

    • 不满足count==3的条件
    • 计算Prcntge=Var*1,执行printf输出1 Percent = 0.07
    • count自增为2
    • 调用RecursvFcnTogetPrcntge()(创建第二个函数栈帧)
  2. 进入第二个RecursvFcnTogetPrcntge()栈帧,此时count=2:

    • 不满足count==3的条件
    • 计算Prcntge=Var*2,执行printf输出2 Percent = 0.14
    • count自增为3
    • 调用RecursvFcnTogetPrcntge()(创建第三个函数栈帧)
  3. 进入第三个RecursvFcnTogetPrcntge()栈帧,此时count=3:

    • 满足条件,直接返回1,回到上一层栈帧(count=2的那个)
  4. 回到count=2的栈帧,此时递归调用已经完成,直接执行return 0,回到count=1的栈帧

  5. 回到count=1的栈帧,执行return 0,回到main函数,程序结束

你之前错误地认为printf是在递归返回后执行的,但实际上它是在发起下一次递归调用之前就执行了,所以输出顺序是1、2,和调用顺序一致。

如果想要看到反向输出,你需要把printf放在递归调用之后,比如修改函数:

int RecursvFcnTogetPrcntge()
{
    if(count==3)
    {
        return 1;
    }

    Prcntge=Var*count;
    count++;
    RecursvFcnTogetPrcntge();
    // 把printf移到递归调用之后
    printf("\n%3d Percent = %.02f",count-1, Prcntge);
    return 0;
}

这样执行时,会先完成所有递归调用,再在回溯阶段依次执行printf,输出顺序就会是2、1,和你最初的预期一致。

另外补充:你说的4个栈帧是对的(main + 3个RecursvFcnTogetPrcntge),但栈帧的执行逻辑是:每个栈帧中,除了递归调用的部分,其他代码都是在当前栈帧创建后立即执行,不是等所有栈帧都创建完再执行。


内容的提问来源于stack exchange,提问作者Pococurante Bird

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 07:01:02