有人可以解释一下这种类型的递归是如何工作的吗?

时间:2014-08-06 15:32:30

标签: c recursion

我在递归中遇到了这个问题。我无法弄清楚它是如何工作的。我理解递归的基础知识但这完全让我感到困惑。请帮忙。

main() { 
    foo(3); 
}

void foo(int x) {
    if (x >= 1) {
        foo(--x);
        printf("%d", x);
        foo(--x);
    }
}

我认为这个节目不打印任何东西,但打印 0120

没有第一次调用foo( - 3),即foo(2)跳转到函数的开头并重复直到3递减到0?

请解释一下这是如何运作的。

3 个答案:

答案 0 :(得分:5)

可以使用递归树解释对foo()的第一次调用:

  prints (in reverse order)

    2 <----------  foo(3)
                  /      \
    1 <----- foo(2)       foo(1) -----> 0
             /   \        /     \
    0 <-- foo(1) foo(0)  foo(0)  foo(-1)
         /    \ 
      foo(0)   foo(-1)

首先,将评估左子树并打印012,然后将评估右子树并打印0。最后你得到了输出:

0120

答案 1 :(得分:4)

所以foo(3)是:

foo(2)
print 2
foo(1)

foo(2)是:

foo(1)
print 1
foo(0)

foo(1)是:

foo(0)
print 0
foo(-1)

现在foo(0)和foo(-1)都是no-ops,所以foo(1)是:

print 0

从那以后,foo(2)就是:

print 0
print 1

foo(3)是:

print 0
print 1
print 2
print 0

这为您提供了观察到的输出。

答案 2 :(得分:1)

这是预期的输出。下一个函数调用被推送到堆栈,并且在前一个函数调用返回之前不会执行printf语句。

foo(3) --> foo(2) --> foo(1) --> foo(0)

现在x不是&gt; = 1,因此不再有函数调用,而foo(0)会弹出堆栈。执行来自foo(1)的printf语句,0(因为x值递减)转到stdout。另一个foo()调用:

foo(3) --> foo(2) --> foo(1) --> foo(-1)
                             //  ^^ second foo() call from foo(1)

当前输出:

0

这没有任何作用。 foo(-1)和foo(1)弹出堆栈 现在printf从foo(2)调用,1进入stdout。

调用foo(0)。

foo(3) --> foo(2) --> foo(0)
                  //  ^^ second foo() call from foo(2)

当前输出:

01

foo(0)什么都不做,然后弹出堆栈的foo(0)和foo(2)
现在我们在foo(3)。打印2并调用foo(1)。

foo(3) --> foo(1)
       //  ^^ second foo() call from foo(3)

当前输出:

012

foo(1)调用foo(0)然后打印0然后调用foo(-1)。现在所有剩余的foo都会弹出堆栈,输出时会得到0120。


@haccks - 看这个程序。有调用foo(-1)。

#include <stdio.h>

void foo(int);

int main() { 
    foo(3); 
    return 0;
}

void foo(int x) {
    if (x >= 1) {
        printf("executing foo with x = %d\n",x-1);
        foo(--x);
        printf("original output: %d\n", x);
        printf("executing foo with x = %d\n",x-1);
        foo(--x);
    }
}

输出:

executing foo with x = 2
executing foo with x = 1
executing foo with x = 0
original output: 0
executing foo with x = -1
original output: 1
executing foo with x = 0
original output: 2
executing foo with x = 1
executing foo with x = 0
original output: 0
executing foo with x = -1