子程序调用返回结构 Main program Subprogram A Subprogram B 5 CALL A CALL B Return Constants CALL B Returm 12 14 Local Constants variables CALL A 1 etc Constants vanables Subprogram return etc Local variables etc CIP 15
子程序调用返回结构
递归子程序 前面讨论的假设是不允许递归,而递归是重要的顺序控制结 构之一。 如LISP中,递归是主要的控制机制。 规约 递归子程序在语法上和其他子程序设计没什么两样,概 念上,也没有困难。 唯一的不同是:递归调用可以在第一个激活的生命期内 创建子程序的第二个激活,如第二个激活再作一次递归 调用,则产生第三个激活,如此进行下去 递归引入的唯一新元素是同一子程序的多个激活可在执 行中某点同时存在
递归子程序 前面讨论的假设是不允许递归,而递归是重要的顺序控制结 构之一。 如LISP中,递归是主要的控制机制。 •规约 递归子程序在语法上和其他子程序设计没什么两样,概 念上,也没有困难。 唯一的不同是:递归调用可以在第一个激活的生命期内 创建子程序的第二个激活,如第二个激活再作一次递归 调用,则产生第三个激活,如此进行下去。 递归引入的唯一新元素是同一子程序的多个激活可在执 行中某点同时存在
实现 由于多个激活同时存在的可能性,我们需要CIP和CEP。 在A中,创建A的一个新激活记录和创建一个子程序B的激活 记录是一样的。在A调用B的情形,A和B的任意两个激活记 录的生命期是不交的,A的生命期完整地包含了B的生命期 在A调用A时,上述性质同样成立。 每个激活记录包含一个返回点,存放值对(ip,ep)。如只观 察ep值,注意到它们形成了一个链表,以创建顺序将激活记 录在中心栈上链在一起。CEP指向栈顶,并可沿ep链(这个 链称为动态链,以程序执行中动态创建的顺序将子程序激活 链在一起)到达较早创建的激活记录。 计算机硬件有时也提供这种中心栈支持,但其实现代价通常 高于简单的无递归的调用一返回结构 将以简单方式实现的子程序和使用中心栈的子程序混合是不 困难,只要编译器能分辨清楚即可 只有实际递归调用的子程序需要中心样,因此,有的语言对 递归子程序给出显式语法标志,有的语言假设子程序总是递 归的
•实现 由于多个激活同时存在的可能性,我们需要CIP和CEP。 在A中,创建A的一个新激活记录和创建一个子程序B的激活 记录是一样的。在A调用B的情形,A和B的任意两个激活记 录的生命期是不交的,A的生命期完整地包含了B的生命期。 在A调用A时,上述性质同样成立。 每个激活记录包含一个返回点,存放值对(ip,ep)。如只观 察ep值,注意到它们形成了一个链表,以创建顺序将激活记 录在中心栈上链在一起。CEP指向栈顶,并可沿ep链(这个 链称为动态链,以程序执行中动态创建的顺序将子程序激活 链在一起)到达较早创建的激活记录。 计算机硬件有时也提供这种中心栈支持,但其实现代价通常 高于简单的无递归的调用—返回结构。 将以简单方式实现的子程序和使用中心栈的子程序混合是不 困难,只要编译器能分辨清楚即可。 只有实际递归调用的子程序需要中心样,因此,有的语言对 递归子程序给出显式语法标志,有的语言假设子程序总是递 归的
7.2数据控制的属性 语言的数据控制特性涉及: 数据在不同执行点的可访问性。 确定数据如何提供给操作,如何存放操作的结果,将结 果又如何取出供以后的操作作为操作数使用 当写程序时,通常知道程序必须执行的操作及其顺序,但对 这些操作的操作数则较少了解。考虑例子。 X:=Y+2*Z 其中有乘、加和赋值三个操作,但操作数是什么呢? 2显然是乘法的操作数,但X、Y、Z仅是标识符,他们不 是操作数,只是以某种方式指定了操作数。如:
7.2 数据控制的属性 语言的数据控制特性涉及: 数据在不同执行点的可访问性。 确定数据如何提供给操作,如何存放操作的结果,将结 果又如何取出供以后的操作作为操作数使用。 当写程序时,通常知道程序必须执行的操作及其顺序,但对 这些操作的操作数则较少了解。考虑例子。 X:=Y+2*Z 其中有乘、加和赋值三个操作,但操作数是什么呢? 2显然是乘法的操作数,但X、Y、Z仅是标识符,他们不 是操作数,只是以某种方式指定了操作数。如:
Y可能是实数、整数或无参数子程序的名字,也 可能由于程序员出错,Y实际上是布尔值、或串、 或语句标号。Y可能指定一个在附近计算的值, 也可能是在较早计算中计算的值(被几层子程序 调用分开),甚至Y可能在程序的不同地方用作 不同的名字。那么,当前Y是什么? 因此,数据控制的中心问题是:Y在这样一个赋值语句 的每次执行中意味着什么? Y可能是局部或非局部变量,问题涉及需知道声明的 作用域规则。 Y可能是形态参数,问题涉及参数传递技术 Y可能是无参数子程序,总是涉及子程序返回结果的 机制
Y可能是实数、整数或无参数子程序的名字,也 可能由于程序员出错,Y实际上是布尔值、或串、 或语句标号。Y可能指定一个在附近计算的值, 也可能是在较早计算中计算的值(被几层子程序 调用分开),甚至Y可能在程序的不同地方用作 不同的名字。那么,当前Y是什么? 因此,数据控制的中心问题是:Y在这样一个赋值语句 的每次执行中意味着什么? Y可能是局部或非局部变量,问题涉及需知道声明的 作用域规则。 Y可能是形态参数,问题涉及参数传递技术。 Y可能是无参数子程序,总是涉及子程序返回结果的 机制