📄 6.4.2.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.0c.htm'"></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='6.4.3.htm'"></img></td>
</tr>
</table>
<br><br>
<font class="title2"><b>6.4.2 不含嵌套过程的词法作用域</b></font>
<table><tr><td>    </td>
<td class="content">
<P>
C语言的词法作用域规则要比Pascal的简单,因为在C中过程定义不能嵌套。即一个过程定义不能出现在另一个过程定义之中。如图6.17所示,一个C程序包含一系列变量说明和过程说明(C中称过程为函数)。如果在某一函数中有对名字a的非局部引用,那么a必须在任何函数以外被说明。在函数以外的一个说明的作用域包括此说明以后所跟的那些函数体,如果名字在某个函数中被重新说明的话,那么作用域是带有洞的。在图6.17中,非局部名字a在readarray,partition和main中的出现是引用第1行中的数组说明。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
<br>
(1) int a[11]; <br>
(2) readarray() {...a...} <br>
(3) int partition(y,z) int y,z; {...a...} <br>
(4) quicksort(m,n) int m,n; {...} <br>
(5) main() {...a...} <br><br>
<b>图6.17</b> 带有a的非局部出现的C程序
<br><br>
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<p>
在没有嵌套过程的情况下,6.3节中对局部名字的栈式存储分配策略可直接用于如C这样的词法作用域语言。在任何过程之外说明的所有名字的存储空间可以静态地进行分配。这个存储空间的位置在编译时刻是已知的,因此如果一个名字在某一过程体中是非局部的,那么我们可以简单地使用此静态确定的地址。而任何其它的名字一定是栈顶上的活动记录的局部名字,可通过top指针进行访问。嵌套过程不能使用这种方法,因为一个局部名字可能引用栈中深处的数据,如下面所讨论的。
</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.0c.htm'"></img></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='6.4.3.htm'"></img></td>
</tr>
</table>
</BODY>
<html><script language="JavaScript">
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -