【问题标题】:Dynamic and Static Scoping动态和静态范围
【发布时间】:2014-10-15 02:36:57
【问题描述】:

我和我的朋友在理解静态和动态范围方面遇到了一些麻烦。我相信对于动态,变量​​(全局)将不断被其他函数更新,直到打印出来,而对于静态,我认为首先分配给变量的任何值都会保持这种状态。

这种想法对吗?

作为一个使用我上面想法的例子,我从这段代码 sn-p 计算了以下内容。

int a, b, c;
void p() {
    int a = 3;
    b = 1;
    c = a + b;
    q();
}
void print() { printf(“%d %d %d\n”, a, b, c); }

void q() {
    int b = 4;
    a = 5;
    c = a + b;
    print();
}
main() {
    int c = 5; 
    p();
} 
Output with static scoping: 315
Output with dynamic scoping: 549

【问题讨论】:

  • 这是关于什么语言的?请添加正确的标签。

标签: scope


【解决方案1】:

使用静态范围,print 将失败,因为 abcprint 内或在 print 定义的范围内都没有赋值 >(即文件的第一行)。

使用动态范围,输出将为 549,因为 abc 中的每一个都在 q 中分配了一个值。您的代码也没有证明,在 qp 内部的调用返回后,local 变量 a 的值 5 在 q 中设置,而不是全局变量.即发生以下情况:

  1. 全局变量 abc 已声明,但没有值。假设您的语言将这些值初始化为 0。

  2. main 被调用。 main 的局部变量 c 被赋予值 5;全局 c 仍然等于 0。

  3. p 被调用。一个p-局部变量a被赋值为3;全局 a 仍为 0。

  4. p 或其调用者main 中不存在局部变量b,因此将全局b 设置为1。

  5. p 中不存在局部变量c,但c 中存在局部变量,其值设置为 3 + 1 = 4。

  6. q 被调用。声明了本地 b 并将其设置为 4,而将全局 b 设置为 0。

  7. q 中不存在局部变量 a,但在其调用者 p 中存在局部变量,因此值从 3 变为 5。

  8. q 或其调用者p 中不存在局部变量c,但在p 的调用者main 中存在,因此该值设置为5 + 4 = 9。全局c 仍为 0。

  9. print 被调用,并且缺少任何本地 abc,它会在其调用链中回溯。它使用来自pa、来自qb 和来自mainc(没有使用任何全局变量。

  10. q 返回。在p 中,ac 的值仍然是q 中设置的5 和9。 b 仍然是 1,因为 q 声明了一个本地 b

  11. p 返回。在main中,我们还有a=0(因为p在调用q之前声明了自己的副本)、b=1(因为p修改了全局b)和c=9(因为@ 987654393@最终将变量局部修改为c)。

  12. main 返回。我们还有全球a=0b=1c=0

如果这令人困惑(我并没有混淆自己并犯任何错误),您可能会理解为什么大多数语言都使用静态作用域:它不仅更容易,而且可能,无需推理即可推断程序的行为运行或模拟它只是为了跟踪变量分配。

【讨论】:

  • 没有。静态作用域的定义是您可以确定在运行程序之前(或)使用哪些变量。静态作用域也称为词法作用域,因为变量作用域可以仅使用程序的文本来解析,而无需了解控制流。换句话说,a 等。在print 中始终引用 3 个全局变量,无论 调用 print 的本地框架中可能存在哪些变量。
  • 如果您的代码 sn-p 是 C,那么在静态类型(C 使用)下,“打印”例程打印全局/文件级变量 a、b 和 c(已声明第 1 行)。它不会“失败”——它具有明确定义的行为。
  • “失败”是一个糟糕的词选择。更准确地说,输出是未定义的(或者更确切地说,取决于语言),因为没有一个全局变量被赋值。
【解决方案2】:

静态作用域- 5 1 9// 它将全局值作为未在打印函数中定义的变量

动态范围 - 5 4 9

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多