Can someone explain the flow of control over this program?

This is an exemplary program in AP Computer Science, and I cannot understand the flow of control over it.

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 ); } 

He outputs this:

 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 

So far, I understand the recursive method and how it recalls itself through:

 mystery( n - 1 ); 

However, I do not see how it can output these five statements after:

 n is zero so no more recursive calls! 

Logically, it looks like it will only indicate:

 We did it again with n = 0 

Can someone help the student and explain to me how he deduces what he did?

+5
source share
5 answers

After n is null, so there will be no more recursive calls! the method continues (the state is pushed onto the stack and then loaded after the method call is completed (n-1).

+2
source

When a function ends, the function it calls has the ability to execute and execute more code.

Here is an illustration of how this recursion happens. Each recursion level is indicated by an increase in indentation.

 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) 
+4
source

Here's a good way to think about recursive programs: when you read the program code, pretend you know what the program does, even if you don't already know it. In your situation, it will look like this:

  • If n == 0 , print a fixed message - that line no more recursive calls!
  • If n != 0 , type n , and then print everything that prints the program for n-1 , and then type n again - in other words, there is a β€œframe” of two messages saying that the program prints for n-1

Here's what it would look like:

 mystery called with n = <something> ... whatever the program prints in between... We did it again with n = <something> 

The first listing takes place before entering the recursive part of the call; the last listing occurs after returning from the recursive part. Note that <something> same as the top and bottom because the value of n stored in each frame of the stack and is set to the previous value when the recursion is expanded.

With this image in place, it’s easy to see that you continue to add nested β€œframes” until you press n==0 , after which you print a message in the middle.

+1
source

The first five times using the mystery method, the method does not stop at a recursive call . This goes on to conclude "we did it again." But I believe that since the secret is blocked, the method is only allowed to complete as soon as the last recursive call is returned. Thus, when you hit n = 0, the first five calls continue until they are initially output, typing "We did it again with n = ..."

0
source

Here's a run of what this recursive method does:

 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 } 
0
source

Source: https://habr.com/ru/post/1242453/


All Articles