之后的java递归值

use*_*818 3 java recursion

我尝试非常简单的测试:

public static void main(String[] args) {
     test(2);
}

public static void test(int i) {
    i--;
    System.out.println("i="+i);
    if (i < 0)
        return;

    System.out.println("test1");
    test(i);
    System.out.println("test2");
    test(i);
}
Run Code Online (Sandbox Code Playgroud)

输出:

i=1
test1
i=0
test1
i=-1
test2
i=-1
test2
i=0
test1
i=-1
test2
i=-1
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么第二次调用(test2)中的变量i之后的值为0已经为0?谢谢.

Mar*_*iot 5

我发现缩进输出将有助于解释这些事情,这里的每个级别对应于调用堆栈的深度(你有多少递归),并且序列对应于何时执行这些事情:

i=1
test1
  i=0 (invoked on the test1 path)
  test1
    i=-1 (invoked on the test1 path)
  test2
    i=-1 (invoked on the test2 path)
test2
  i=0 (invoked on the test2 path)
  test1
    i=-1 (invoked on the test 1 path)
  test2
    i=-1 (invoked on the test 2 path)
Run Code Online (Sandbox Code Playgroud)

请注意,在每个缩进级别下,标题"test1"和"test2" test下都有调用,这是因为您在每个标题下递归调用,因此在每次执行时test都会递归两次.

让我们稍微备份并采取一个更简单的案例,如果你要执行test(1),你会期望看到:

i=0
  test1
    i=-1
  test2
    i=-1
Run Code Online (Sandbox Code Playgroud)

因为您test在标题"test1"和"test2"下调用,导致两个路径被导航,一个路径位于"test1"标题下,另一个路径位于"test2"标题下.

当你调用时test(2),你的代码粗略地这样做:(省略递归)

(i = 2)
Decrement i  (i = 1)
Print i
Print "test1"
Call test(i) (test(1))
Print "test2"
Call test(i) (test(1))
Run Code Online (Sandbox Code Playgroud)

...并且记住,每次调用时test(1),您的代码大致都会这样:(省略递归)

(i = 1)
Decrement i  (i = 0)
Print i
Print "test 1"
Call test(i) (test(0))
Print "test 2"
Call test(i) (test(0))
Run Code Online (Sandbox Code Playgroud)

如果将第一个块中的每个调用替换为块的输出,test(1)您将看到它正好生成输出.

基本上,你得到两个i=0打印,因为你在每个函数调用中递归两次.