0

我无法理解我们回来的作业的答案。我相信我对“嵌套”函数的概念感到困惑,但也许这是错误的。我正在寻找一些关于从以下代码中分配动态和静态范围值的帮助。

x : integer -- global

procedure set_x(n : integer)
    x := n
end

procedure print_x
    write_integer(x)
end

procedure first
    set_x(1)
    print_x
end

procedure second
    x : integer
    set_x(2)
    print_x
end

// program starts here
set_x(0)
first()
print_x
second()
print_x

Static Scoping Output: 1122
Dynamic Scoping Output: 1121

当我经历每一个时,我的想法:

静止的:

  • Run set_x(0),由于 n 的参数,这会产生一个局部变量,但是由于我们将 x 设置为 n 而没有在本地声明 x (int x =..),因此我们将全局 x 更新为 0。
  • Run first(),它执行set_x(1),它遵循相同的逻辑将 x 全局更新为 1。然后我们首先在其中运行print_x,它打印出 1 的全局 x。
  • Run print_x,它只是重新打印 1。
  • 运行second()我们在本地声明 x 并运行set_x(2),它会将 2 更新为 n。(因为是set,而不是second过程,对吧?然后我们运行它的print_x过程来打印 2。
  • 再次运行print_x它只会转储 2。
  • 结果 1122

动态的(对这个更困惑)

  • 运行set_x(0)将 x 和全局 x 设置为 0。
  • 运行first()我们set_x再次点击并将 x 更新为 1。我们打印 1。
  • 运行print_x我们重新打印 1。
  • 运行second()我们在本地创建 x,我们运行set_x(2)并将全局 x 设置为 2。然后我们打印 2。
  • 运行print_x最后我们再次重新打印,这里是我猜的 2,但答案应该是 1。
  • 我的猜测是 1122,实际答案是 1121

我对动态的最后一部分以及为什么它是 1 而不是 2 感到困惑。

4

1 回答 1

0

在某些地方很难遵循您的推理,因为您没有说出 x认为正在打印或更新的内容,而这几乎就是整个蜡球。

要记住的重要一点是静态作用域(也称为词法作用域)在编译时完全确定。定义某事物的位置决定了它的静态范围。

动态范围当然是相反的。它是在运行时确定的。执行的位置决定了它的动态范围。

所以,看一下set_x程序。它没有x自己的局部变量,它是在全局范围内定义的,因此在静态范围内,它只能更新全局x。无论在哪里调用它都是如此,即使在second过程中也是如此。

但是,在动态作用域下,set_x内部调用会second更新x本地到 的second,而保持全局x不变。

请注意,无论范围规则如何,最后一次print_x调用将始终打印 global (因为该过程是在全局范围内定义的,并且对的调用是在全局范围内执行的)。所以不同的是,使用静态作用域,程序结束时 global 为 2;但使用动态范围,全局为 1。xprint_xprint_xxx

于 2014-10-16T21:57:00.273 回答