我正在解决静态和动态范围中的以下代码问题。 我得到了以下答案,但我需要有人确认我是否正确,因为我有点困惑。如果有人能以简单的方式解释,我真的很感激!
Static => (1)8 (2)27
Dynamic => (1)10 (2)27
proc main
var x,y,z;
proc sub1
var x,z
x := 6;
z := 7;
sub2;
x := y*z + x;
print(x); ---- (2)
end;
proc sub2
var x,y
x := 1;
y := x+z+2;
print(y); ---- (1)
end;
begin
x := 1; y:=3; z:=5;
sub1;
end
答案 0 :(得分:5)
作用域定义了代码中的变量标识符(即名称)映射到实际变量的规则。
静态(或词法)作用域确定映射,根据程序代码结构映射变量名称。首先搜索直接范围(即伪语言中proc
.. end
之间的块),即引用变量的范围,搜索变量声明。如果它在那里,名称绑定到此变量。如果不是,则在父作用域中查找名称(基于代码结构 - 即程序文本),祖父母等等。
在您的情况下,在sub2
中,在表达式x+z+2
中,x始终引用局部变量(在同一范围内定义),z始终引用{{1中定义的变量proc - 此映射不依赖于实际的程序执行。因此,对于静态作用域,main
指的是值为x
的局部变量,1
指的是z
中的变量,其值为main
,因此结果是5
。请注意,在5+1+2=8
中,sub1
和x
是局部变量 - 即z
不会更改z := 7
中的z
。
动态作用域类似于静态作用域,因为它首先在直接作用域中查找变量,然后继续查看作用域的祖先。但是,在使用静态作用域时,作用域层次结构由程序文本确定,通过动态作用域,层次结构由程序生成的子程序调用的层次结构确定 - 即作用域层次结构和调用堆栈相似。
使用动态范围,在main
点,callstack如下:(1)
。因此main -> sub1 -> sub2
中的名称首先在sub2
中查找(sub2
名称解析为x
局部变量,与静态作用域一样),然后在x
中(sub1
名称解析为z
中的z
变量),然后解析为sub1
。
因此main
解析为值x
的变量,1
解析为z
的变量,其值为sub2
,结果为{ {1}}。最后,7
中的10
在y
中查找,然后在sub2
中查找(因为调用堆栈为sub2
),因此表达式结果为{{ 1}}是main
- 这与静态作用域相同,因为静态(词法)作用域层次结构和动态(基于调用)层次结构在此执行点是相等的。