📄 6.4.1.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.0.htm'"></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='6.4.2.htm'"></img></td>
</tr>
</table>
<br><br>
<font class="title2"><b>6.4.1 块</b></font>
<table><tr><td>    </td>
<td class="content">
<P>
一个块(Block)是一个含有它自己的局部数据说明的语句。块的概念,或称分程序的概念,来自Algol。而在C语言中,一个块的语法为:
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<P>
{declarations(若干个说明) statements(若干个语句)}
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<p>
块的一个特征是它们的嵌套结构。定界符号标志着块的开始和结束。在C语言中使用花括号{ 和 }作为定界符号,而Algo1使用begin和end。定界符号确保一个块与另一个块要么是独立的,要么一个块完全嵌入在另一个块之中。即对于块B1和块B2,不可能出现这种重叠情况:Bl开始,然后B2开始,而B1比B2早结束。这种嵌套的性质有时称作块结构。
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<p>
在块结构语言中,说明的作用域由最近嵌套规则给出:
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<p>
1.在块B中的一个说明的作用域包括B。
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<p>
2.如果名字x在块B中没有说明,那么,x在B中的出现是在一个外围块B'中的x的说明的作用域之内,并且使得:
<BR> (a)B'中有x 的说明,
<BR> (b)B'是包围B的,相对于其它任何具有名字x 的说明且包围B 的块而言,B'是离B 最近的。
</td></tr></table>
<table><tr>
<br>
<table width="40%" align=center border=1 cellspacing=0 cellpadding=5>
<tr>
<td width="60%" height=30 align=center>说明</td>
<td width="40%" align=center>作用域</td>
</tr>
<tr>
<td align=left>
<p>int a = 0;</p>
<p>int b = 0;</p>
<p>int b = 1;</p>
<p>int a = 2;</p>
<p>int b = 3;</p>
</td>
<td align=center>
<br>
<p><center>B0-B2</center></p>
<p><center>B0-B1</center></p>
<p><center>B1-B3</center></p>
<p><center>B2</center></p>
<p><center>B3</center></p>
</td>
</table>
<br>
<table width="90%" align=center border=0>
<tr>
<td width="10%"></td>
<td width="90%">
rain()<br>
{<br>
:    int a = 0;<br>
:    int b = 0;<br>
:    {<br>
:    :    int b = 1;<br>
:    :    {<br>
:    :    ... int a = 2;<br>
:    :    B2 printf("%d%d\n",a,b); (印出十进制数a,b并换行)<br>
:    :    ...<br>
:    :    }<br>
B0   B1  {<br>
:    :    ...<br>
:    :    B3 int b = 3;<br>
:    :    ... printf("%d%d\n",a,b);<br>
:    :    }<br>
:    :    printf("%d%d\n",a,b);<br>
:    }<br>
:    printf("%d%d\n",a,b);<br>
}<br>
</td>
</tr>
</table>
<p><center><b>图6.15</b>  在一个C程序中的块</center></p><br>
</tr></table>
<table><tr><td>    </td>
<td class="content">
<p>
在图6.15中所设计的C语言程序的每一个说明把被说明的名字初始化为该说明所在的块的序号。在B0中的b的说明的作用域不包括B1,因为b在B1中重新被说明,在图中用B0-B1 来表示。这样的一个间隙称作是在说明的作用域中的一个洞(hole)。
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<p>
最近嵌套作用域规则将反映在图6.15的程序的输出中。控制恰好自块的源程序正文开始之前的一点处流人,并且恰好流出到块的源程序正文结束之后的一个位置,于是打印语句执行的顺序是B2,B3,B1和B0,即控制离开块的顺序。在这些块中的a和b之值是:
<br>
2
1 <br>
0
3 <br>
0
1 <br>
0
0 <br>
</p>
</td></tr></table>
<table><tr><td>    </td>
<td class="content">
<p>
块结构可以用栈式存储分配实现。由于说明的作用域不会超出它所在的块,在进入块时可以为被说明的名字分配空间,并当控制离开该块时释放空间。对于图6.15中的块B0,我们可以如图6.16所显示的那样进行分配。局部名字a和b的角标标明它是在哪个块中被说明的。注意a2 和b3可能分配在同一空间中,因为它们所在的块不在同一时刻存活。
</p>
</td></tr></table>
<table><tr>
<br>
<table width="15%" align=center border=1 cellspacing=0 cellpadding=5>
<tr>
<td align=center>a0</td>
</tr>
<tr>
<td align=center>b0</td>
</tr>
<tr>
<td align=center>b1</td>
</tr>
<tr>
<td align=center>a2,b3</td>
</tr>
</table>
<p><center><b>图6.16</b>  在图6.15中说明的名字的存储</center></p>
<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.0.htm'"></img></td>
<td><img src="../images/next.gif" onmouseover="javascript:style.cursor='hand'" onclick="vbscript:window.location.href='6.4.2.htm'"></img></td>
</tr>
</table>
</BODY>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -