📄 6.4.4.htm
字号:
<html>
<head>
<title>编译原理</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<link type="text/css" rel="stylesheet" href="../css/specification.css">
</head>
<body>
<table align=right width=300>
<tr>
<td><img src="../images/previous.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='6.4.3_3b.htm'"></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='6.5.0.htm'"></img></td>
</tr>
</table>
<br><br>
<font class="title2"><b>6.4.4 动态作用域</b></font>
<table><tr><td>    </td>
<td class="content">
<P>
在动态作用域规则下,当一个新的活动记录建立起来时,非局部名字所联编到的存储不发生变化。即在被调用活动中的一个非局部名字a要引用在这次调用活动中a所引用过的同样的存储单元。而新的联编是为被调用过程的局部名字建立的;这些名字将引用新的活动记录中的存储空间。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
在图6.21中的程序说明了动态作用域。在(3)—(4)行上的过程show印出非局部名r的值。若在Pascal中的词法作用域之下,非局部名r是在第(2)行的说明的作用域之内,所以程序的输出为
<br> 0.250 0.250 <br>
0.250 0.250<br>
然而,如果在动态作用域之下,输出为 <br>
0.250 0.125 <br>
0.250 0.125 <br>
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
当在主程序中的(10)-(11)行上调用show时,印出 0.250,因为局部于主程序的变量被用到。然而,当show在small之内的第(7)行上被调用时,印出0.125,因为用到的是局部于sma1l的变量r 。
</p>
</td></tr></table>
<table width="493"><tr><td width="16">    </td>
<td class="content" width="463">
<P>(1) <b><font color="#0000FF">program</font></b> dynamic(input,output); <br>
(2) <b><font color="#0000FF">var</font></b> r:real; <br>
(3) <b> <font color="#0000FF">procudure</font></b> show; <br>
(4) <span class="down"><span class="up"><b>
<font color="#0000FF">begin</font></b></span></span> write(r: 5:3) <b><font color="#0000FF">end</font></b>; <br>
(5) <b> <font color="#0000FF">procedure</font></b> small; <br>
(6) <b> <font color="#0000FF">var</font></b> r: real;<br>
(7) <b> <font color="#0000FF">begin</font></b> r:=0.125; show <b><font color="#0000FF">end</font></b>; <br>
(8) <b> <font color="#0000FF">begin</font></b> <br>
(9) r:=0.25;<br>
(10) show; small; write1n; <br>
(11) show; small; writeln <br>
(12) <b> <font color="#0000FF">end</font></b>.<br>
<b>图6.21</b> 输出依赖于所用的作用域规则</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
下面两种实现动态作用域的方法分别与在静态作用域的实现中使用存取链与display表具有某些类似。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
<font class="emphasize">1.深访问。</font>从概念上讲,如果存取链指向与控制链所指的相同的活动记录则得到动态作用域。一种简单的实现方法是删除存取链,使用控制链在栈中搜索,以寻找包含所需非局部名字的存储单元的第一个活动记录。“深访问”意味着搜索可能要进行到栈的深处。搜索进行的深度取决于给予程序的输入,而不能在编译时刻确定。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
<font class="emphasize">2.浅访问。</font>这种方法的思想是在静态分配的存储空间中存放每一个名字的现行值。当过程p开始一次新的活动时,p中的非局部名n占用对于n静态分配的存储空间。先前的n值可以存放在p的活动记录中并且当p的活动记录结束时必须给以恢复。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
以上两种方法可以进行比较。深访问方法访问一个非局部名字需要较长的时间,但它不需要有关活动开始和结束的附加开销。另一方面,浅访问可以允许直接查找非局部名字,但是在活动开始和结束时需要花费时间维持这些值。
</p>
</td></tr></table>
<br>
<table align=right width=300>
<tr>
<td><img src="../images/previous.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='6.4.3_3b.htm'"></img></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='6.5.0.htm'"></img></td>
</tr>
</table>
</BODY>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -