Java 在跟踪该程序时,我可以使用什么样的图表方法来保持所有内容的有序性?

Java 在跟踪该程序时,我可以使用什么样的图表方法来保持所有内容的有序性?,java,trace,diagramming,Java,Trace,Diagramming,这是我的一道自学作业题 我应该写下这个程序的输出,而不是实际运行它。 我理解这里传递的所有语法和变量(我有答案),但出于某种原因,在纸上追踪它是行不通的 有没有什么秘密的图表技术可以让一切都井然有序 对一个有经验的程序员来说,手工解决这个问题仅仅是儿戏吗 谢谢 public class Mystery extends ConsoleProgram { public void run() { ghost(13); } private void ghost(int x) { int

这是我的一道自学作业题

我应该写下这个程序的输出,而不是实际运行它。 我理解这里传递的所有语法和变量(我有答案),但出于某种原因,在纸上追踪它是行不通的

有没有什么秘密的图表技术可以让一切都井然有序

对一个有经验的程序员来说,手工解决这个问题仅仅是儿戏吗

谢谢

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;
}
}
公共类扩展控制台程序{
公开募捐{
鬼(13);
}
私有虚空重影(int x){
int y=0;
对于(int i=1;i
由于
run()
main()
可见的唯一方法(因此能够被调用),因此您只需要执行变量到值的替换。当变量出现并生成时,将其值放入


一旦你掌握了替换变量值的诀窍就不难了,这是一种非常宝贵的调试策略。

你能做的就是在一张纸上模拟每个作用域(思考方法),在纸上写下所有变量

如果你调用一个方法,你需要一张新的纸,并把它放在现有的纸堆上。如果你从一个方法中返回,你会把最上面的一块抛向另一个方向。如果你有课程,你需要一张单独的表格

这就是你能做的。但没有一个真正的程序员能做到这一点

你要做的是:

  • 通过查看代码了解基本结构。比如:在打印“鬼魂”之前,它会多次调用“巫婆”

  • 为了理解您指导的详细信息,请使用logging/systemout语句和/或调试器仔细检查您的想法,并实际执行代码

那么,这个练习是没有用的吗?别这么想。虽然你不能独立完成这项工作,但这是思考代码的一部分,你总是以这样或那样的方式完成这项工作。

你可以展开循环:

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

这里没有递归,所以剩下的应该很简单。

试着用传入的数字写下一堆方法调用,例如:

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

在每次方法调用时,找到一些临时空间,写出变量,并尝试计算代码的作用,直到得到返回值。然后获取该返回值并返回到该方法堆栈中的最后一点,然后删除该方法

例如,上面示例堆栈的顶部(底部)是
skeleton(13,1)
,因此您尝试计算当x为13,y为1时
skeleton()返回的内容。很简单,它是
1
。然后返回堆栈,看看返回值应该是什么。在本例中,它是
witch()
,因此堆栈是:

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

然后继续,直到run()完成。

通常我使用的表有两列(内存和监视器) 像这样:

====================
| Memory | Monitor |
====================
|        |         |
|        |         |
|        |         |
|        |         |
====================
内存就像调试中的手表。 监视器是将在监视器中输出的内容

例如:

int x; // Declare X (Memory)
x=10; // fill with 10 (Memory)
System.out.println(x); // print it (Monitor)
如果我使用该表:

====================
| Memory | Monitor |
====================
| x=10   | 10      |
|        |         |
|        |         |
|        |         |
====================
我希望这对你有帮助

更新: 我想更详细地解释一下:

让我们看看我以前创建的代码

1. int x; // Declare X (Memory)
2. x=10; // fill with 10 (Memory)
3. System.out.println(x); // print it (Monitor)
步骤1: 我声明了X,所以这个表是这样的:

====================
| Memory | Monitor |
====================
| x      |         |
|        |         |
|        |         |
|        |         |
====================
====================
| Memory | Monitor |
====================
| x=10   |         |
|        |         |
|        |         |
|        |         |
====================
步骤2: 我用10填充x,然后如下所示:

====================
| Memory | Monitor |
====================
| x      |         |
|        |         |
|        |         |
|        |         |
====================
====================
| Memory | Monitor |
====================
| x=10   |         |
|        |         |
|        |         |
|        |         |
====================
步骤3: 我打印x

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

我相信我能找到答案,但作为一名经验丰富的程序员,我编写单元测试并修改代码,直到通过为止。如果你发现这段代码让人困惑,这并不是你有什么问题,它似乎是为了让人困惑。我认为唯一让人困惑的是
y
的值,如果你是一个有经验的程序员,它不是第一次(几次)通过时看起来的值。这是一个好方法,除了不使用整张纸之外,只需在同一张纸上用方框表示新页面,当您离开该方法时,只需划掉方框并更新调用方法的变量。谢谢各位,先生们,我将再一次艰难地完成它。我喜欢把它插入到编译器中,然后摆弄它直到它正常工作。明白了!我希望我再也不用这样做了。