-3

使用 DYNAMIC SCOPING 的给定伪代码的输出是什么?在这里,我想知道将打印的 x 值是多少。

它只是一种类似于 C 但具有动态作用域的语言中的简单伪代码。

    integer x,y;

    p(integer n){
        x=(n+2)/(n-3);
    }

    q(){
        integer x,y;
        x=3;
        y=4;
        p(y);
        write(x);
    }

    main(){
        x=7;
        y=8;
        q();
        write(x);
    }
4

2 回答 2

1

由于我首先误解了您的问题并为 C 词法范围提供了答案,因此让我们将其保留为比较。

C 样式范围

符号 x 和 y 将对应于 2 个可能的变量

让我们称 x0, y0 为在顶层声明的变量,而 xq, yq 为在 q 中声明的变量。

x0 = 7
y0 = 8
q -> 
   xq = 3
   yq = 4
   p(4) ->
      x0 = 6 // (4+2)/(4-3)
   write(xq) // OUTPUT: 3
write(x0)    // OUTPUT: 6

动态范围

我们将显示符号绑定堆栈以跟踪符号当前值

x0 = 7 // x:(x0)
y0 = 8 // y:(y0)
q ->        // declaring x,y in q -> x:(x0,xq) y:(y0,yq) 
   xq = 3   // x:(x0,xq)
   yq = 4   // y:(y0,yq)
   p(4) ->
      xq = 6 // x:(x0,xq)
   write(xq) // OUTPUT: 6
             // leaving q -> x:(x0) y:(y0)
write(x0)    // OUTPUT: 7

这个例子很好地说明了动态范围的危险性/复杂性:

在 p 中,x 的值取决于执行路径,并且查看代码,知道我们是在修改局部变量还是全局变量的唯一方法是在心理上重新创建程序流程。在较为复杂的情况下,这很快就会变得相当困难。

非动态范围允许更容易地遵循给定标识符的范围(只需追溯静态范围链)。

于 2014-01-25T02:37:47.157 回答
0

对于动态范围,每个标识符都有一个全局绑定堆栈。引入一个名为 x 的局部变量会将绑定推送到全局 x 堆栈(可能为空),当控制流离开范围时,该堆栈会弹出。在任何上下文中评估 x 总是产生顶部绑定。换言之,全局标识符是指与最近的环境相关联的标识符。请注意,这不能在编译时完成,因为绑定堆栈只存在于运行时,这就是为什么这种类型的作用域被称为动态作用域。http://en.wikipedia.org/wiki/Scope_(computer_science)

阅读了这个理论..如果我使用动态范围来回答这个问题首先当 main() 被调用时 x=7 并且 y=8 被推入堆栈然后当 q() 被调用时它推 x=3 和 y=4 ;现在 p(n) 没有声明 x,因此它将使用最后一次调用 x 作为 q() 中的声明,并将其值更新为“6”。

那么当 q() 的作用域结束时,它的值将从堆栈中弹出,并且全局调用的 x=7 和 x=8 的值将保留在那里,因此 x=7 将被打印。

ANS:打印 6 和 7

于 2014-01-25T03:28:27.757 回答