2
class RecTest
{
    int values[];

    RecTest(int i)
    {
        values=new int[i];
    }

    void pray(int i)
    {
        if (i==0) return;
        else 
        {       
            System.out.println(+values[i-1]);
            pray(i-1);
        }
    }
}

class aka
{
    public static void main(String h[])
    {
        RecTest ob=new RecTest(10);
        int i;
        for(i=0;i<10;i++)
            ob.values[i]=i;
        ob.pray(10);
    }
}

该程序运行良好,它按降序打印 9,8,7,6,5,4,3,2,1,0。但是当我交换 System.out.println(+values[i-1]) 和 gray(i-1) 语句时,它会按升序打印 0 到 9。

有人可以解释一下为什么会这样吗?

我就是想不通。Source-Java-2,完整参考,第 5 版,第 171 页

4

3 回答 3

7

无论您是在堆栈中打印还是返回堆栈,它都在改变。要么打印当前数字,然后更深,要么更深,然后打印当前数字。

3 >
    2 >
        1 >
        print 1
    print 2
print 3

或者

3
print 3 >
         2
         print 2 >
                  1
                  print 1
于 2012-05-20T04:39:33.883 回答
2

当您参加本节时

System.out.println(+values[i-1]);
pray(i-1);

并切换它们,想想代码的进展。

执行步骤进入祈祷,但在它可以打印任何东西之前,它被再次发送到祈祷,(这次 i = 8),在它可以打印之前,它再次被发送到祈祷(i = 7) .

最后,在这个链条的深处,祈祷最终退出。当 i = 0 时,pray 会返回,执行放缓的链条开始展开。

链中最低的打印被调用(当 i = 0 时),然后那个祈祷方法退出,并且链中的下一个打印被调用(i = 1)......等等......

像这样可视化递归代码有点困难,但是试着想象一下当你的方法第一次从 main 调用时的确切执行流程,并逐步完成它。此外,如果您仍然看不到发生了什么,使用调试器单步执行可能会有所帮助。

于 2012-05-20T04:41:35.153 回答
1

以这种方式编写,您的代码显示“打印 i-1,然后执行其他所有操作”。所以它打印 9,然后继续其他数字。在这种情况下,“做其他事情”意味着打印 8、7 等等。但重要的是,首先打印 9。

但是如果你把这两行代码颠倒过来,它会说“做其他所有事情,然后打印 i-1”。所以它处理其他数字,然后打印 9。在这种情况下,“处理”意味着打印 ...、7、8。但重要的是,最后打印 9。

于 2012-05-20T04:52:28.773 回答