【问题标题】:What sort of diagramming method could I use to keep everything organized while tracing through this program?在跟踪该程序时,我可以使用哪种图表方法来保持一切井井有条?
【发布时间】:2014-11-01 11:45:02
【问题描述】:

这是我的自学作业之一。

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

有什么秘密的图表技术可以让一切井井有条吗?

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

谢谢

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

【问题讨论】:

  • 我确信我能弄明白,但作为一个有经验的程序员,我会编写单元测试并更改代码直到它通过。如果您发现这段代码令人困惑,这并不是您有什么问题,它似乎是为了混淆。
  • 我认为唯一令人困惑的是y 的值,如果您是一位经验丰富的程序员,这并不是第一次(少数)通过时看起来的那样(es )。

标签: java trace diagramming


【解决方案1】:

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

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

等等

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

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

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

并继续直到 run() 完成。

【讨论】:

    【解决方案2】:

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

    ====================
    | 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      |         |
    |        |         |
    |        |         |
    |        |         |
    ====================
    

    第 2 步: 我用 10 填充 x,然后看起来像这样:

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

    第 3 步: 我打印 x

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

    【讨论】:

      【解决方案3】:

      您可以做的是在一张纸上实际模拟每个范围(思考方法),并在其中写下所有变量。

      如果你调用一个方法,你会拿一张新纸并将它放在现有的纸堆上。如果你从一个方法返回,你会把最上面的一块扔掉。如果您有课程,则需要单独的表格。

      这是你可以做的。但是没有真正的程序员会这样做。

      你要做的是:

      • 通过查看代码了解基本结构。比如:它会在打印“ghost”之前调用“witch”几次。

      • 用于了解您指导的详细信息,并使用日志记录/系统输出语句和/或调试器仔细检查您的想法并实际执行代码。

      那么锻炼没用吗?不要这么想。虽然你不是自己做的,但它是思考代码的一部分,你总是以一种或另一种方式这样做。

      【讨论】:

      • 这是一个很好的方法,除了不是使用整张纸,而是在同一张纸上用一个框表示新页面,当您离开该方法时,只需将框划掉并更新调用方法的变量。
      【解决方案4】:

      您可以展开循环:

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

      变成

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

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

      【讨论】:

      • 谢谢各位先生 - 我又一次费力地完成了。我喜欢将它插入编译器并摆弄它直到它正常工作的想法。
      • 知道了!我希望我再也不用做这些了。
      【解决方案5】:

      由于run()main() 可见的唯一方法(因此能够被调用),因此您只需要执行变量到值的替换。在变量出现和生成时将其值放入其中。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-22
        • 2016-10-16
        • 2015-01-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多