程序语言理解 - 静态与动态范围

时间:2014-10-16 19:36:10

标签: scope scoping dynamic-scope

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

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

我经历过每一个人的想法:

静态:

  • 运行set_x(0),由于参数为n,这会产生局部变量,但由于我们将x设置为n而未声明x local(int x = ..),因此我们将全局x更新为0。 / LI>
  • 运行first(),其执行set_x(1),它遵循相同的逻辑全局更新x到1。然后我们首先运行print_x,打印全局x为1。
  • 运行print_x,只需重新打印1。
  • 运行second()我们在本地声明x并运行set_x(2),将更新2更新为n。 (因为set而不是second程序,对吧?然后运行其print_x程序打印2。
  • 再次运行print_x转出2。<​​/ li>
  • 产生于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。

1 个答案:

答案 0 :(得分:0)

在某些地方跟你的推理很难,因为你没有说你认为正在打印或更新的 x,这几乎是整个蜡

要记住的重要一点是静态作用域(也称为词法作用域)在编译时完全确定。 定义的东西确定其静态范围。

动态范围当然是相反的;它是在运行时确定的。 执行的地方确定其动态范围。

因此,请查看set_x程序。它没有自己的本地x,并且它在全局范围内定义,因此在静态作用域下,它只能更新全局x。即使在second程序中,也无论在何处调用它都是如此。

但是,在动态范围设定下,set_x内的second次呼叫会更新x secondx保持全局print_x不变。 / p>

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