Java 递归调用在函数中已完成,但继续打印整数

Java 递归调用在函数中已完成,但继续打印整数,java,recursion,methods,while-loop,Java,Recursion,Methods,While Loop,我试图研究如果在递归调用之后编写一些代码会发生什么,下面是代码。我试图追踪代码,但我不知道发生了什么。我认为一旦我的程序打印出x的最后一个值,函数就会终止,因为x的值不满足if循环条件。我执行了这个代码,结果是不可理解的。任何帮助都将不胜感激 public class Recursive { public static void main(String []args){ int a=5; call(a); } public static

我试图研究如果在递归调用之后编写一些代码会发生什么,下面是代码。我试图追踪代码,但我不知道发生了什么。我认为一旦我的程序打印出x的最后一个值,函数就会终止,因为x的值不满足if循环条件。我执行了这个代码,结果是不可理解的。任何帮助都将不胜感激

public class Recursive {

    public static void main(String []args){
        int a=5;
        call(a);
    }

    public static void call(int x) {
        System.out.print(x+"\n");
        if(x>0) {
            x--;
            call(x);
        }
        System.out.print(x);
     }
}
预期输出:
543200


我的输出:
5 4 3 2 1 0 0 0 1 2 3 4

您可以尝试使用If条件并删除最后一次打印,而不是while

public static void call(int x) {
   System.out.print(x+"\n");

   if (x>0) {
      x--;
      call(x--);
   }
}

你忘了说什么是令人惊讶或困惑的,这表明你不理解这个问题(因此投了两张反对票)。以下是我认为可能令人困惑的地方。减量运算符
x--
首先返回变量的值,然后降低其值。所以如果你跑

 z= 25
 dothedoo(z--)
dothedoo中的值将是25,而不是24。或者--x将首先降低该值,然后返回该值

这是您的代码

   public static void call(int x) {
      System.out.print(x + "\n");
      while (x > 0) {
         x--;
         call(x);
      }
   }

让我们考虑这个调用栈,输入x=2</p>

  • 1) 电话(2)
  • 2) 打印x//2
  • 2) x——(变为1)
  • 3) 递归调用调用(1)//记住调用(2)现在已挂起
  • 4) 打印x//1
  • 5) x--(变为0)
  • 6) 对调用(0)的递归调用//记住调用(2)和调用(1)现在已挂起
  • 7) 打印x//0
  • 8) x--(变成-1)
  • 9) 递归调用call(-1)//中断循环,因为它与条件不匹配,恢复流到挂起的调用(1)函数
  • 10) 有关x的值,请参阅步骤5
  • 11) 中断调用(1)函数的循环。//恢复挂起的呼叫(2)
  • 12) 参考步骤2,其中x仍然为1

  • 13) 继续另一个通话(1)

  • 14) 这将导致打印额外的0;来自步骤13中的调用
你的while循环把程序搞乱了

递归中的变量是按值传递的,因此实际 执行此操作时,调用方的值x不会在调用方中全局递减
call(x)
x之后使用的值 递归调用中的递减是您拥有的x的一个副本 在调用方中递减

请参考此以了解更多信息


此外,根据本答案中提供的解释,
while循环
在这里是臭名昭著的,您实际需要的是
if循环

为什么您说程序没有终止?它应该终止得很好。虽然是意外的打印,但它应该从问题中的内容终止——铅笔和纸的追踪时间!您应该向我们展示您的预期输出和当前程序输出。你的情况就像,你看到一只正在飞行的独角兽,你在问“那只独角兽为什么会飞?”而不是“哇,现在我知道独角兽会飞了”。只是一个类比。我期望输出类似于5 4 3 2 1 0 0。程序输出是5 4 3 2 1 0 0 0 1 2 3 4我用if替换了while。我在if循环之后添加了一个System.out.print(x)。结果中有一些规律。我只是想知道为什么会这样?问题不在于x——问题在于递归调用中的传递值以及在这种情况下对递归的理解。我觉得两张反对票有点苛刻。哇,谢谢你,伙计,你是真正回答我问题的人,如果可以的话,我会投你一票。另一个问题,你所说的呼叫(x)暂停是什么意思?为什么它会恢复回呼叫?这在java中正常吗?或者是因为我有while loopwell,这在java或其他语言中是正常的,除非您使用的是线程。当您从函数b()调用函数a()时,执行将等待函数a()完成其任务,然后函数b()恢复执行。如果我确实回答了你的问题,我就看不到我的答案下面的勾号;):-D哈哈。