Java 调试递归函数

Java 调试递归函数,java,debugging,recursion,Java,Debugging,Recursion,我在下面一步一步地看这段代码,我不明白的是“离开”n值是如何变成2,5和10的。我理解递归调用的第一部分,直到n==0,return将控制移到else部分并打印(0%2)。节目不应该在那之后停止吗 void fun2(int n){ System.out.println("Entering"+n); if(n==0) return; else{ fun2(n/2); System.out.print("Leaving"+n+"

我在下面一步一步地看这段代码,我不明白的是“离开”n值是如何变成2,5和10的。我理解递归调用的第一部分,直到n==0,return将控制移到else部分并打印(0%2)。节目不应该在那之后停止吗

void fun2(int n){
    System.out.println("Entering"+n);
    if(n==0)
        return;
   else{
        fun2(n/2);
        System.out.print("Leaving"+n+"---->");       
        System.out.println(n%2);
    }
}
输出:

      Entering5
      Entering2
      Entering1
      Entering0
      Leaving1---->1
      Leaving2---->0
      Leaving5---->1
      Leaving10---->0

首先,我认为您的输出有错误。当我通过调用值为5的
fun2()
来运行上述代码时,我会得到您指示的所有输出,除了
Leaving10-->0这一行。您确定这是在
fun2()
函数的输出中,还是在调用
fun2()
的代码位置的工件中?也许您正在调用值为10的
fun2()
函数,并将输出的第一行
输入10

此函数通过计算每个二进制数字的值来工作。这是使用%运算符完成的,在else块的最后一行中称为模运算符(也称为余数运算符):
System.out.println(n%2)

每次迭代都会计算下一个较低的2次方,因为它是用
n/2
调用的。请记住,这里处理的是整数除法,因此没有余数。1/2=0,而不是0.5。但是,整数模函数可以正常工作,因此1%2=1(1除以2=0,余数为1)

下面详细介绍了该方法的每个递归级别:

  • n=5,n/2=2,fun2(2),n%2=1
  • n=2,n/2=1,fun2(1),n%2=0
  • n=1,n/2=0,fun2(0),n%2=1
  • n=0,方法返回
  • 当您将单个控制台输出放在一起时,会得到101,这是5的二进制值

    如果使用参数值10调用
    fun2()
    ,则会看到输出
    1010

    1010 = (1*2^3) + (0*2^2) + (1*2^1) + (0*2^0) = 8 + 0 + 2 + 0 = 10
    

    首先,我认为您的输出有错误。当我通过调用值为5的
    fun2()
    来运行上述代码时,我会得到您指示的所有输出,除了
    Leaving10-->0这一行。您确定这是在
    fun2()
    函数的输出中,还是在调用
    fun2()
    的代码位置的工件中?也许您正在调用值为10的
    fun2()
    函数,并将输出的第一行
    输入10

    此函数通过计算每个二进制数字的值来工作。这是使用%运算符完成的,在else块的最后一行中称为模运算符(也称为余数运算符):
    System.out.println(n%2)

    每次迭代都会计算下一个较低的2次方,因为它是用
    n/2
    调用的。请记住,这里处理的是整数除法,因此没有余数。1/2=0,而不是0.5。但是,整数模函数可以正常工作,因此1%2=1(1除以2=0,余数为1)

    下面详细介绍了该方法的每个递归级别:

  • n=5,n/2=2,fun2(2),n%2=1
  • n=2,n/2=1,fun2(1),n%2=0
  • n=1,n/2=0,fun2(0),n%2=1
  • n=0,方法返回
  • 当您将单个控制台输出放在一起时,会得到101,这是5的二进制值

    如果使用参数值10调用
    fun2()
    ,则会看到输出
    1010

    1010 = (1*2^3) + (0*2^2) + (1*2^1) + (0*2^0) = 8 + 0 + 2 + 0 = 10
    

    这是调试的一种方法。另一种方法是在调试器中逐行执行。此外,此代码的行为与您所期望的有什么不同?我不知道离开如何获得输入的“n”值。我几乎不需要使用递归,所以跟踪这项任务看起来相当混乱。你能解释一下吗?这不是我的代码。我刚刚添加了printsA递归函数调用与任何其他函数调用没有区别。如果
    funcA()
    调用
    funcB()
    ,则将保留
    funcA()
    范围内的值,直到
    funcB()
    返回。在递归调用的情况下也会发生同样的情况。很抱歉,我似乎仍然不明白。输出的这一部分令人困惑。导致控件以n=1进入else部分并进行打印的返回似乎是我所能追踪到的全部。之后,控件再次返回导致打印此Leaving2-->0 Leaving5-->1 Leaving10-->0的else部分的打印语句。这是调试的一种方法。另一种方法是在调试器中逐行执行。此外,此代码的行为与您所期望的有什么不同?我不知道离开如何获得输入的“n”值。我几乎不需要使用递归,所以跟踪这项任务看起来相当混乱。你能解释一下吗?这不是我的代码。我刚刚添加了printsA递归函数调用与任何其他函数调用没有区别。如果
    funcA()
    调用
    funcB()
    ,则将保留
    funcA()
    范围内的值,直到
    funcB()
    返回。在递归调用的情况下也会发生同样的情况。很抱歉,我似乎仍然不明白。输出的这一部分令人困惑。导致控件以n=1进入else部分并进行打印的返回似乎是我所能追踪到的全部。之后,控件再次返回导致打印此Leaving2-->0 Leaving5-->1 Leaving10-->0的else部分的打印语句。为什么会发生这种情况。