简单的递归函数无法提供预期的输出

时间:2019-04-27 03:19:31

标签: c

对不起,如果我做错了,我对C真的很陌生,以前没有使用过堆栈溢出。我试图用手跟踪此简单的递归函数,但从编译的代码中得到了不同的答案。

我的思考过程是

打印2 | n = 2-1 = 1 | 1> = 0 |倒数计时(1)

打印1 | n = 1-1 = 0 | 0> = 0 |倒数计时(0)

打印0 | n = 0-1 = -1 | -1不是> = 0 |

打印-1 |结束

void countdown(int n)
{
    printf ("n = %d\t", n);
    n--;
    if (n >= 0)
    {
        countdown(n);
    }
    printf ("n = %d\t", n);
}

int main ( )
{
    countdown(2);
    return 0;
}

我希望得到:n = 2 n = 1 n = 0 n = -1

但是编译后的代码给了我:n = 2 n = 1 n = 0 n = -1 n = 0 n = 1

我不确定-1之后的0和1来自何处

3 个答案:

答案 0 :(得分:1)

您的代码执行以下操作(省略if):

#innodb_force_recovery = 1

对于n = 2:

countdown(n):
     print(n)
       countdown(n-1)
     print(n-1)

答案 1 :(得分:0)

您的代码没有问题。只需删除第二个printf代码即可。

void countdown(int n)
{
    printf("n = %d\t", n);
    n--;
    if (n >= 0)
        countdown(n);
}

int main()
{
    countdown(2);
    return 0;
}

结果是:

n = 2 n = 1 n = 0

这是我在2nd printf捕获时的调用堆栈。

StudyCpp.exe!countdown(int n) line 16   C++  // It is 2nd printf of countdown(0). Now, n is -1. 
StudyCpp.exe!countdown(int n) line 14   C++  // It called countdown(0)
StudyCpp.exe!countdown(int n) line 14   C++  // It called countdown(1)
StudyCpp.exe!main() line 21 C++   // It called countdown(2)

如果再进行一次调试,则可以看到如下所示的调用堆栈:

StudyCpp.exe!countdown(int n) line 16   C++  // It is 2nd printf of countdown(1) after executed countdown(0).
StudyCpp.exe!countdown(int n) line 14   C++  // It called countdown(1)
StudyCpp.exe!main() line 21 C++   // It called countdown(2)

而且,如果再进行一次调试,则可以看到如下所示的调用堆栈:

StudyCpp.exe!countdown(int n) line 16   C++  // It is 2nd printf of countdown(2) after executed countdown(1).
StudyCpp.exe!main() line 21 C++   // It called countdown(2)

最后,程序将退出。

答案 2 :(得分:0)

这里您递归地调用countdown(),被称为三次。
实际上,每个递归调用都会将countdown()推入堆栈。

SF1(Bottom of stack) ---> SF2 ---> SF3 (Top of stack). 

现在将执行顶部的框架。
从函数返回期间,将弹出特定的堆栈框架。
现在,堆栈帧指针指向SF2,然后指向SF1。

考虑程序,以下是流程。
推送操作
SF1将首先被压入堆栈

n = 2 printed.  
Again n updated to 1

SF2已推送:

n = 1 got printed.  
Again n updated to 0

SF3已推送:

n = 0 got printed.  
Again n updated to -1.  
But n <= 0, So if check fails.  

弹出操作
现在,SF3首先从堆栈中弹出。

n = -1 printed  

然后SF2弹出

prints n = 0.

最后SF1

n = 1 printed