What sort of diagramming method could I use to keep everything organized while tracing through this program?

StackOverflow https://stackoverflow.com/questions/11814096

  •  24-06-2021
  •  | 
  •  

Frage

Here is one of my self-study homework problems.

I am supposed to write down the output of this program without actually running it. I understand all the syntax and the variable-passing here, (and I have the answers) but for some reason, tracing it out on paper isn't working.

Is there some secret diagramming technique that keeps everything organized?

Is figuring this out by hand mere child's play to an experienced programmer?

Thanks

public class Mystery extends ConsoleProgram {
public void run() {
    ghost(13);
}

private void ghost(int x) {
    int y = 0;
    for (int i = 1; i < x; i *= 2) {
        y = witch(y, skeleton(x, i));
    }
    println("ghost: x = " + x + ", y = " + y);
}

private int witch(int x, int y) {
    x = 10 * x + y;
    println("witch: x = " + x + ", y = " + y);
    return x;
}

private int skeleton(int x, int y) {
    return x / y % 2;
}
}
War es hilfreich?

Lösung

You can unroll loops:

for (int i = 1; i < 13; i *= 2) {
    E[i]
}

becomes

E[1]; E[2]; E[4]; E[8];

There's no recursion here, so the rest should be straightforward.

Andere Tipps

Try writing down a stack of method calls with the number that's been passed in, example:

run()
ghost(13)
skeleton(13,1)

etc.

At each method call, find some scratch space and write out the variables and try to work out what the code does until you get a return value. Then take that return value and go back to the last point in that method stack and scratch that method off.

For example, the top (bottom) of the above example stack is skeleton(13,1), so you try to work out what skeleton() returns when x is 13 and y is 1. Easy enough, it's 1. Then go back to the stack and see what that return value should go. In this case it's witch(), so the stack is:

run()
ghost(13)
witch(0,1)

and continue until run() is finished.

Usually I use table that have 2 column(Memory and Monitor) Like this:

====================
| Memory | Monitor |
====================
|        |         |
|        |         |
|        |         |
|        |         |
====================

Memory is like watch in debug. Monitor is what will output in monitor

So for example:

int x; // Declare X (Memory)
x=10; // fill with 10 (Memory)
System.out.println(x); // print it (Monitor)

If i trace use that table:

====================
| Memory | Monitor |
====================
| x=10   | 10      |
|        |         |
|        |         |
|        |         |
====================

I hope this will help you

UPDATE: I want to explain more detail:

Let's take a look with code that i created before

1. int x; // Declare X (Memory)
2. x=10; // fill with 10 (Memory)
3. System.out.println(x); // print it (Monitor)

Step 1: I declare X. So the table look like this:

====================
| Memory | Monitor |
====================
| x      |         |
|        |         |
|        |         |
|        |         |
====================

Step 2: I fill x with 10 then look like this:

====================
| Memory | Monitor |
====================
| x=10   |         |
|        |         |
|        |         |
|        |         |
====================

Step 3: I print x

====================
| Memory | Monitor |
====================
| x=10   | 10      |
|        |         |
|        |         |
|        |         |
====================

What you can do is to actually emulate every scope (think method) on a sheet of paper, where you write down all the variables.

If you call a method you take a new piece of paper and put it on the stack of existing paper. If you return from a method you throw the top most piece a way. If you have classes you would need a separate sheet for those.

That is what you could do. But no real programmer does that.

What you do instead is:

  • understand the basic structure from looking at the code. Things like: It will call "witch" a couple of time before it will print "ghost".

  • for understanding the details you guide and double check your thoughts with logging/system out statements and / or the debugger and actually executing the code.

So is the exercise useless? Don't think so. While you don't do it on its own it is part of thinking about code and you do that all the time one way or the other.

Since run() is the only method that is visible to main() (and thus capable of being called), you would only need to perform variable-to-value substitution. Place the value of the variables in as they come along and are generated.

It isn't hard once you get the hang of substituting variable values, which is an invaluable debugging tactic.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top