Java 有人能解释一下这个程序的控制流程吗?
这是我AP计算机科学课程中的一个示例程序,我无法理解它的控制流程Java 有人能解释一下这个程序的控制流程吗?,java,Java,这是我AP计算机科学课程中的一个示例程序,我无法理解它的控制流程 public static void mystery( int n ) { System.out.println( "mystery called with n = " + n ); if ( n == 0 ) { System.out.println( "n is zero so no more recursive calls!" ); return; } mystery
public static void mystery( int n )
{
System.out.println( "mystery called with n = " + n );
if ( n == 0 )
{
System.out.println( "n is zero so no more recursive calls!" );
return;
}
mystery( n - 1 );
System.out.println( "We did it again with n = " + n );
}
public static void main( String[] args )
{
mystery( 5 );
}
它的输出是:
mystery called with n = 5
mystery called with n = 4
mystery called with n = 3
mystery called with n = 2
mystery called with n = 1
mystery called with n = 0
n is zero so no more recursive calls!
We did it again with n = 1
We did it again with n = 2
We did it again with n = 3
We did it again with n = 4
We did it again with n = 5
到目前为止,我了解递归方法以及它如何通过以下方式调用自身:
mystery( n - 1 );
但是,我不知道它如何在以下情况下输出这五条语句:
n is zero so no more recursive calls!
从逻辑上讲,它似乎只会说:
We did it again with n = 0
有人能帮一个学生解释一下它是如何输出它所做的吗?在“n”为零之后,这样就没有递归调用了方法继续(状态被放在堆栈上,然后在方法(n-1)调用完成后加载。当函数完成时,调用它的函数有机会完成并执行更多代码 下面是这个递归是如何发生的一个例子。 每个递归级别都由缩进的增加表示
mystery(5):
"mystery called with n = 5"
mystery(4):
"mystery called with n = 4"
mystery(3):
"mystery called with n = 3"
mystery(2):
"mystery called with n = 2"
mystery(1):
"mystery called with n = 1"
mystery(0):
"mystery called with n = 0"
"n is zero so no more recursive calls!"
mystery(0) returns
"We did it again with n = 1"
end of mystery(1)
"We did it again with n = 2"
end of mystery(2)
"We did it again with n = 3"
end of mystery(3)
"We did it again with n = 4"
end of mystery(4)
"We did it again with n = 5"
end of mystery(5)
下面是一种思考递归程序的好方法:当您阅读程序代码时,即使您还不知道该程序的功能,也要假装您知道该程序的功能。在您的情况下,这种情况如下所示:
- 如果
,打印固定消息-这就是n==0
字符串不再递归调用!
- 如果
,则打印n!=0
,然后打印程序为n
打印的内容,然后再次打印n-1
——换句话说,程序为n
打印的内容周围有一个由两条消息组成的“框架”n-1
mystery called with n = <something>
... whatever the program prints in between...
We did it again with n = <something>
n=
…无论程序在两者之间打印什么。。。
我们用n=
第一次打印输出发生在进入调用的递归部分之前;最后一次打印输出发生在从递归部分返回之后。请注意,
在顶部和底部是相同的,因为n
的值存储在每个堆栈帧上,并在递归展开时设置为上一个值
此图片很容易看到,你一直添加嵌套的“框架”,直到你点击<代码> n== 0 ,此时你在中间打印消息。
神秘方法前五次,<强>该方法不会在递归调用< /强>停止。但我认为,由于神秘是阻塞的,所以只有在返回最后一个递归调用后,才允许该方法结束。因此,在命中n=0时,前五个调用继续执行其原始结论,打印“我们使用n=…”这是该递归方法的运行过程:
mystery(5): {
| println( "mystery called with n = 5" );
|
| n != 0:
| skip return
|
| mystery(n - 1) is mystery(4)
|
| call mystery(4): {
| | println( "mystery called with n = 4" );
| |
| | n != 0:
| | skip return
| |
| | mystery(n - 1) is mystery(3)
| |
| | call mystery(3): {
| | | println( "mystery called with n = 3" );
| | |
| | | n != 0:
| | | skip return
| | |
| | | mystery(n - 1) is mystery(2);
| | |
| | | call mystery(2): {
| | | | println( "mystery called with n = 2" );
| | | |
| | | | n != 0:
| | | | skip return
| | | |
| | | | mystery(n - 1) is mystery(1);
| | | |
| | | | call mystery(1): {
| | | | | println( "mystery called with n = 1" );
| | | | |
| | | | | n != 0:
| | | | | skip return
| | | | |
| | | | | mystery(n - 1) is mystery(0);
| | | | |
| | | | | call mystery(0): {
| | | | | | println( "mystery called with n = 0" );
| | | | | |
| | | | | | n == 0:
| | | | | | return from mystery(0)
| | | | | }
| | | | |
| | | | | back inside mystery(1), continue executing where we left off
| | | | | println("We did it again with n = 1")
| | | | | method ends; return to caller
| | | | }
| | | |
| | | | back inside mystery(2), continue executing where we left off
| | | | println("We did it again with n = 2")
| | | | method ends; return to caller
| | | }
| | |
| | | back inside mystery(3), continue executing where we left off
| | | println("We did it again with n = 3")
| | | method ends; return to caller
| | }
| |
| | back inside mystery(4), continue executing where we left off
| | println("We did it again with n = 4")
| | method ends; return to caller
| }
|
| back inside mystery(5), continue executing where we left off
| println("We did it again with n = 5")
| method ends; program ends
}
例如,将神秘(n-1)替换为神秘(n--);并查看它如何不再执行此操作。当n==0时,它会在打印之前返回,因此当n==0时它不会打印任何内容。以前的操作是递归调用,现在在n==0时完成,因为当n==0时它不会递归调用自己,所以执行将在代码中继续打印。