第六章 顺序控制
第六章 顺 序 控 制
顺序控制提供了操作和数据被组合成程序和程序集合的框架 涉及两个方面的问题:操作执行顺序的控制(顺序控制) 以及数据在子程序间的传递(数据控制)(下一章) 61隐式和显式顺序控制 顺序控制结构可分为三组 1、用于表达式中的结构(也针对语句,表达式是语句的基 本建筑块)。如:优先级规则和括号 2、用于语句或语句组间的结构。如:条件和迭代 3、用于子程序间的结构,如:子程序调用和协同例程 这种分法并不是精确的,如LⅠSP和APL中只有表达式而无语 顺序控制结构可以是隐含的(缺省的)(由语言定义、程序 员可显式修改)或显式的(程序员可用来显式地修改隐含顺 序)
顺序控制提供了操作和数据被组合成程序和程序集合的框架。 涉及两个方面的问题:操作执行顺序的控制(顺序控制), 以及数据在子程序间的传递(数据控制)(下一章) 6.1 隐式和显式顺序控制 顺序控制结构可分为三组: 1、用于表达式中的结构(也针对语句,表达式是语句的基 本建筑块)。如:优先级规则和括号。 2、用于语句或语句组间的结构。如:条件和迭代。 3、用于子程序间的结构,如:子程序调用和协同例程。 这种分法并不是精确的,如LISP和APL中只有表达式而无语 句。 顺序控制结构可以是隐含的(缺省的)(由语言定义、程序 员可显式修改)或显式的(程序员可用来显式地修改隐含顺 序)
62算术表达的顺序控制 考虑方程求根: B±√B2-4×A×C root 2×A 该公式至少涉及15个分开的操作,用汇编或机器语言至少需 要15条指令甚至更多。而写成 Fortran程序则为: ROOT=(B+SQRT(B**2-4 *A*C)/(2*A) 这是自然的表达方法,由翻译器而不是程序员来考虑各种优 化问题。 然而,翻译器如何控制正确的操作顺序?
6.2 算术表达的顺序控制 考虑方程求根: 该公式至少涉及15个分开的操作,用汇编或机器语言至少需 要15条指令甚至更多。而写成Fortran程序则为: ROOT=(-B+SQRT(B**2-4*A*C))/(2*A) 这是自然的表达方法,由翻译器而不是程序员来考虑各种优 化问题。 然而,翻译器如何控制正确的操作顺序? A B B A C root − − = 2 4 2
树结构表示 目前,我们将表达式考虑为单个实体,忽略了其计值必须的 实际语法和语义。 表达式中的基本顺序控制机制是“函数复合”:刻划操作及 其操作数 函数复合是表达式呈树结构特征,根为主操作,中间节点为 中间层次操作,叶为操作数。如图6.1,求方程根的表达式的 树表示阐明了表达式的控制结构,低层的数据引用和操作作 为高层操作的操作数,必须先计值,但树表示也留下一些计 值顺序没有指定 如:一B和B*2谁先计值?B是否可组合为同一引用? 通常语言定义只在树表示级定义表达式计值顺序,允许实现 者决定计值细节
树结构表示 目前,我们将表达式考虑为单个实体,忽略了其计值必须的 实际语法和语义。 表达式中的基本顺序控制机制是“函数复合”:刻划操作及 其操作数。 函数复合是表达式呈树结构特征,根为主操作,中间节点为 中间层次操作,叶为操作数。如图6.1,求方程根的表达式的 树。 树表示阐明了表达式的控制结构,低层的数据引用和操作作 为高层操作的操作数,必须先计值,但树表示也留下一些计 值顺序没有指定。 如:-B和B**2谁先计值?B是否可组合为同一引用? 通常语言定义只在树表示级定义表达式计值顺序,允许实现 者决定计值细节
平方根公式的表示 2 A SORT B A
平方根公式的表示
表达式的语法 表达式可表示为树结构,但为了在程序中表示,线性化是 需要的。 前缀(波兰前缀)记法。 这是波兰数学家发明的无括号记号法 如:fxy,z) X+ab-ca LISP使用了该记号法的变种,称为剑桥波兰,用括号 将操作符及其操作数括起来,如:(X(+ab-ca)。 后缀(逆波兰)记号法 类似于前缀,但操作符数在后面,如: ab+ca-X 中缀记号法 最适合二元操作,也是我们最常用的方式
•表达式的语法 表达式可表示为树结构,但为了在程序中表示,线性化是 需要的。 •前缀(波兰前缀)记法。 这是波兰数学家发明的无括号记号法。 如:f(x,y,z) ×+ab-ca LISP使用了该记号法的变种,称为剑桥波兰,用括号 将操作符及其操作数括起来,如:(X(+ab)(-ca))。 •后缀(逆波兰)记号法 类似于前缀,但操作符数在后面,如: ab+ca-× •中缀记号法 最适合二元操作,也是我们最常用的方式
表达式(a+b)×(C-a)的树结构
表达式(a+b)×(c-a)的树结构
表达式的语义 上三种记号法对语言的设计都有一些有用的属性,在如何计 算表达式值方面也有不同。 前缀计值 可以通过一遍扫描计值每个表达式,然而需要知道每个 操作的操作数量。除了可省去括号外,前缀表达式在语 言设计中有如下价值 般的函数调用均采用前缀方式。 2、可表示有任意数量操作数的操作,写表达式只需 个语法规则。 3、解码可以机械地很容易地进行,将其翻译成简单 代码序是容易的。 下面算法用一个执行栈计值表达式:对表达式P, 1、如P中下一项是操作子,压入栈项,设置所需参数 数目。 2、如P中下一项是操作数,压入栈项 3、如栈项n项是操作数(对栈中第一个n元操作), 则可以进行计值,用计值结果替代该操作符和操作数
•表达式的语义 上三种记号法对语言的设计都有一些有用的属性,在如何计 算表达式值方面也有不同。 •前缀计值 可以通过一遍扫描计值每个表达式,然而需要知道每个 操作的操作数量。除了可省去括号外,前缀表达式在语 言设计中有如下价值: 1、一般的函数调用均采用前缀方式。 2、可表示有任意数量操作数的操作,写表达式只需 一个语法规则。 3、解码可以机械地很容易地进行,将其翻译成简单 代码序是容易的。 下面算法用一个执行栈计值表达式:对表达式P, 1、如P中下一项是操作子,压入栈项,设置所需参数 数目。 2、如P中下一项是操作数,压入栈项。 3、如栈项n项是操作数(对栈中第一个n元操作), 则可以进行计值,用计值结果替代该操作符和操作数
后缀计值 后缀计值时,操作符紧跟其操作数后而且操作数已被计值 1、如P中下一项是操作数,压入栈顶 2、如P中下一项是n元操作符,n个参数必须是栈顶部 的n个元素,计算结果并替换这n个元素 这种计值策略直接、简单,是很多翻译器中生成表达 式代码的基础 中缀计值 中缀是常见的,但用于程序语言中会导致一些问题 1、只适合于二元操作。语言单用中缀是不够的,还需 使用前缀,这二者的混合使翻译更为复杂。 2、表达式中涉及多个中缀操作时,如不使用括号,则 存在固有二义性。为解决这个问题,通常引入隐含的 规则
•后缀计值 后缀计值时,操作符紧跟其操作数后而且操作数已被计值。 1、如P中下一项是操作数,压入栈顶 2、如P中下一项是n元操作符,n个参数必须是栈顶部 的n个元素,计算结果并替换这n个元素。 这种计值策略直接、简单,是很多翻译器中生成表达 式代码的基础。 •中缀计值 中缀是常见的,但用于程序语言中会导致一些问题: 1、只适合于二元操作。语言单用中缀是不够的,还需 使用前缀,这二者的混合使翻译更为复杂。 2、表达式中涉及多个中缀操作时,如不使用括号,则 存在固有二义性。为解决这个问题,通常引入隐含的 规则
操作子计值顺序 X X 3 3
操作子计值顺序