Java 这个递归循环代码是如何执行的

Java 这个递归循环代码是如何执行的,java,recursion,Java,Recursion,我有一些代码行,我无法理解代码是如何执行的,我指的是程序流 代码: 我认为输出应该是:0 但输出为:0,0,1 我做过很多次以上的调试, 我在调试时看到的流程: 从第3行开始执行,即以2作为参数调用printit() 第6行,如果条件检查nvalue(如果大于零),则控制转到第7行,即prinit()再次通过递减n值进行调用 步骤2:继续执行,直到n值变为0,如果条件为false,则执行第6行。所以在第9行,SYSO打印0 然后,无法理解,控件如何再次从第10行转到第5行?? 在第一次调用时,n

我有一些代码行,我无法理解代码是如何执行的,我指的是程序流

代码:

我认为输出应该是:0

但输出为:0,0,1

我做过很多次以上的调试, 我在调试时看到的流程:

  • 从第3行开始执行,即以2作为参数调用printit()
  • 第6行,如果条件检查
    n
    value(如果大于零),则控制转到第7行,即prinit()再次通过递减n值进行调用
  • 步骤2:继续执行,直到n值变为0,如果条件为false,则执行第6行。所以在第9行,SYSO打印0
  • 然后,无法理解,控件如何再次从第10行转到第5行??

  • 在第一次调用时,
    n
    为2

    if(n>0){ // 2, note this is an if - not a while loop.
      printit(--n); // recurses, after this n = 1; references won't update by the recursion.
                    // Well, not with primitives or immutable types anyway.
      // n = printit(n - 1); // <-- This would behave like you seem to expect.
      // n = printit(--n);   // <-- and so would this, but not in C!
    }
    
    System.out.print(n+","); // prints 1 !!!!
    return n; // <- returns 1
    
    if(n>0){//2,注意这是一个if-not-while循环。
    printit(--n);//递归,在此n=1之后;引用不会通过递归更新。
    //好吧,不管怎样,不是使用原语或不可变类型。
    
    //n=printit(n-1);//让我用调试模式一步一步地解释一下

    请在调试模式下自下而上查看方法堆栈。

    因为它是一个递归方法,在
    n>0
    之前都是自己调用的。这意味着这个方法有三个调用,如下所示

    现在它将返回值并从方法堆栈中返回,如下面的快照所示

    最后,它将返回到调用它的
    main
    方法


    由于此方法被调用了三次,因此您得到的是
    0,0,1,
    不要考虑递归方法调用,而是首先考虑任何方法调用。例如,如果您在main中调用一个方法,程序执行将转到该方法并执行该方法中的所有代码。一旦该方法执行完毕,程序流将返回返回main并继续执行main中的代码行。这同样适用于递归调用

    在第一次使用2运行时,2大于0。因此,将2减为1,然后调用
    printIt(1)
    。这意味着程序调用的函数运行完毕后将返回此处。但由于printIt()是递归的,因此下一次调用还将等待其内部的任何方法调用

    因此,在下一次调用中,n现在是1,大于0。您将其递减为0,然后调用
    printIt(0)
    。当此事件运行时,它未通过
    if(n>0)
    检查,并继续到第9行打印0,然后返回

    既然完成了,程序将返回到第二次调用
    printIt()
    。记住,在这次调用中,n是0。它现在可以继续自己的第9行并打印0。然后,这将重复到原来对打印1的
    printIt()
    的调用


    因此,当所有的操作都完成后,您将得到0,0,1。

    在这个程序中,
    printit()
    调用了三次

    控件如何再次从第10行转到第5行

    以下是控制流程:

    • printit(0)
      --
      n=0
      ,打印
      “0,
      ,返回0
    • printit(1)
      --
      n=1
      ,打印
      “0,
      ,返回0
    • printit(2)
      --
      n=2
      ,打印
      “1,
      ,返回1
    • main()
    因此输出为:
    0,0,1,
    为了更好地理解,在调试时在return语句中放置断点

    以下是控制/内存流程图:

    编辑1:或者图像解释:

    尝试使用调试器跟踪每个函数中的“n”值。缺少的一件事是:在第7行中对
    printit()的递归调用完成后,将执行函数的其余部分。每次调用
    printit()时
    在递归调用完成后打印输出,因此它基本上会在递归的“退出”过程中打印三个输出。这就是为什么输出是三个值的集合,而不是像您所期望的那样只有一个值。您正在调用printit()请详细说明这一行:
    return n;//因为2-1是一个。执行线程从递归返回,现在如果您有
    n=printit(-n);
    ,那么您将获得预期的输出。
    if(n>0){ // 2, note this is an if - not a while loop.
      printit(--n); // recurses, after this n = 1; references won't update by the recursion.
                    // Well, not with primitives or immutable types anyway.
      // n = printit(n - 1); // <-- This would behave like you seem to expect.
      // n = printit(--n);   // <-- and so would this, but not in C!
    }
    
    System.out.print(n+","); // prints 1 !!!!
    return n; // <- returns 1