程序设计语言与编译原理-控制结构课件_第1页
程序设计语言与编译原理-控制结构课件_第2页
程序设计语言与编译原理-控制结构课件_第3页
程序设计语言与编译原理-控制结构课件_第4页
程序设计语言与编译原理-控制结构课件_第5页
已阅读5页,还剩75页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第三章控制结构主要讨论语言中描述算法的机制,即控制结构。主要讨论各种语句级控制结构和单元级控制结构。控制结构:程序员用来规定程序各个成分(语句和程序单元)的执行流程的控制部分语句级控制结构单元级控制结构1

3.2语句级控制结构顺序(sequencing)选择(selection)重复(repetition)语句级控制结构:语言用来构造各种语句执行顺

序的机制语句级控制结构分为三种:2语言可用的、最简单的控制结构。顺序运算符(语句结束标记)

;一.顺序3复合语句若干个语句可以通过顺序运算符组在一起作为一个单独的语句.复合语句括号:

begin…end

{…}二.选择选择控制结构允许程序员在某些可选择的语句中选择其中一条来执行。

单选ifthen二选一ifthenelse多选一嵌套ifthenelse或case…1.单选ifthen

max:=a;

if

(a<b)

thenmax:=b;

可供选择的语句max:=b要么执行要么不执行if

(a>b)then

max:=aelse

max:=b;可供选择的语句max:=a和

max:=b只选择其中一个执行2.二选一

ifthenelse

选择结构引起二义性

ifx>0thenifx<10thenx:=0elsex:=1000怎样解决if语句的二义性?ALGOL68中if语句的结束符号fi;Ada用endif;例如:ifx>0thenifx<10thenx:=0elsex:=1000fifiifx>0thenifx<10thenx:=0fielsex:=1000fiPL/1和PASCAL语言采用“最近匹配原则”,即else匹配最近的then:ifx>0thenifx<10thenx:=0elsex:=1000等价于ifx>0thenbeginifx<10thenx:=0elsex:=1000endALGOL60加入begin..end来消除二义性:ifx>0thenbeginifx<10thenx:=0elsex:=1000endifx>0thenbeginifx<10thenx:=0endelsex:=100083.多选一嵌套的ifthenelse

ifathenS1

elseifbthenS2

elseifcthenS3

elseS4fififi

①PL/1的select结构

SELECT:

WHEN(A)S1;

WHEN(B)S2;

WHEN(C)S3;

OTHERWISES4;

END9多选一的简洁表达

②多种语言的case语句:PASCALALGOL68Adavaroperator:char;operand1,operand2,result:boolean;……caseoperatorof

‘.’:result:=operand1andoperand2;

‘+’:result:=operand1oroperand2;

‘=’:result:=operand1=operand2;end10

不同语言case语句的差异:ALGOL68中,case语句基于整表达式的值,表达式的值为i,则选择第i个分支执行。PASCAL显式列出可能的值,表达式的值与分支的值相同时,选择该分支。每个分支在case中出现的次序是无关紧要的。表达式的值不在显式列出的值中时的处理:out和otherwise;11Java中Switch语句的选择结构switch(表达式){case常量表达式1:语句1;case常量表达式2:语句2;

…….case常量表达式n:语句n;default:语句n+1;}switch语句判断条件只能接受byte,char,int,short型一旦碰到第一次case匹配,就会开始顺序执行以后所有的程序代码,而不管后面的case条件是否匹配,后面case条件下的语句都会被执行,直到碰到break语句为止。12class

SampleSwitch

{

public

static

void

main(String

args[])

{

for(int

i=0;

i<6;

i++)

switch(i)

{

case

0:

System.out.println("i

is

zero.");

break;

case

1:

System.out.println("i

is

one.");

break;

case

2:

System.out.println("i

is

two.");

break;

case

3:

System.out.println("i

is

three.");

break;

default:

System.out.println("i

is

greater

than

3.");

}

}

}

133.Dijkstra选择结构ifB1→S1B2→S2B3→S3…...BN→SNfi其中,Bi是布尔表达式,称为卫哨。若有多个卫哨为真时执行任一Si。特性:非确定性例如计算A和B的最大值,可写成ifABMAX:=BABMAX:=Afi14三.重复当预先知道重复次数时,在循环计数器值的有限集合上重复。①FORTRAN的DO循环中,用标号控制循环体

DO7I=1,10A(I)=0B(I)=0

7CONTINUE

1.计数器制导15

②Pascal的for语句计数重复的值可在任何有序集上for...tofor...downto16

for语句for(表达式一;表达式二;表达式三){

执行语句;}表达式一:初始化表达式;表达式二:循环条件表达式;表达式三:循环后的操作表达式。表达式一表达式三执行语句表达式二结束falsetrue17for(inti=0;i<10;i++){System.out.println(i);}inti=0;for(;i<10;i++){System.out.println(i);}inti=0;for(;i<10;){System.out.println(i);i++;}inti=0;for(;;){if(i>=10)break;System.out.println(i);i++;}等效

18①while循环:描述0或任意多次的重复②repeatuntil循环:至少一次以上的重复

2.条件制导

19while语句while(条件表达式语句){

执行语句

}intx=1;While(x<3){System.out.println(“x=”,x);x++;}注:while表达式的括号后面一定不能加;

20

Dijkstra的卫哨命令表示法doB1→S1B2→S2......BN→SNod重复执行直到没有Bi为真。若有多个Bi为真,任选一个Si执行。21

顺序、选择和重复可以帮助程序员组织语句的控制流程,是基本控制工具。顺序、选择、重复是一定意义的抽象;

四、语句级控制结构分析22抽象控制结构顺序是按程序计数器提供的顺序获得指令的一种抽象。选择和重复是对显式修改程序计数器的值的抽象---无条件转移和条件转移控制既简单又有效。抽象控制结构比显式控制结构:修改指令计数器的低级控制机制更好。

面向问题:程序员通过使用顺序、选择和重复的一般模式就能较好地表达控制语句执行的意图。高级语言控制结构最终要由条件转移和无条件转移的低级代码实现。与程序员无关,将由编译器生成有效的机器代码,因而采用高度抽象概念有利于程序设计。ifBthenSifBgotoB.true

gotoS.nextB.true:…S的代码S.next:BSYNifBthenS1elseS2ifBgotoB.true

gotoB.falseB.true:…S1的代码

gotoS.nextB.false:…S2的代码S.next:BS1S2YNfor(i=1;iN;i++)Si:=1;again:ifiNgotoB.truegotoS.next

B.true:…

S的代码i:=i+1;

goto

againS.next:

计算机科学先驱EdsgerWybeDijkstra1930年出生在荷兰鹿特丹市。Dijkstra曾是开发Algol的委员会成员。编写了第一个Algol60编译器。他发明或帮助定义的概念包括结构化编程、堆栈、向量、信号量和同步过程。29

1968年,提出并写下了一篇著名的论文:《GoTo语句是有害的》。1972年,Dijkstra荣获美国计算机协会的图灵奖。2002年8月6日,去世,享年72岁。Dijkstra精彩言论编程的艺术就是处理复杂性的艺术。优秀的程序员很清楚自己的能力是有限的,所以他对待编程任务的态度是完全谦卑的,特别是,他们会象逃避瘟疫那样逃避“聪明的技巧”——1972年图灵奖演讲计算机科学是应用数学最难的一个分支,所以如果你是一个蹩脚的数学家,最好留在原地,继续当你的数学家。实际上如果一个程序员先学了BASIC,那就很难教会他好的编程技术了:作为一个可能的程序员,他们的神经已经错乱了,而且无法康复。就语言的使用问题:根本不可能用一把钝斧子削好铅笔,而换成十把钝斧子会使事情变成大灾难。简单是可靠的先决条件。30大多数程序设计语言提供goto语句,这是随意修改程序计数器值的抽象。

Dijkstra于1968年发表了著名论文,论述了goto语句对程序设计的影响。结论:包含许多goto语句的程序隐含许多出错的机会。关于goto语句大多数语言提供了丰富的控制结构,通常也提供了goto语句。语言提供怎样的控制结构?

对这个问题仍然有争议。

一些语言(

如Java)吸取了Diikstra的建议,废弃goto语句,使程序逻辑更加清晰。但为了实现控制转移,特别设计了break

语句和continue

语句,从而实现“有节制”地使用goto语句。回顾C语言的处理方法。控制结构的选择至今仍不清楚究竟应该提供哪些专门的控制结构,才能更好地满足程序设计的所有需要。虽然各种语言建立了多种多样的控制结构,但至今没有一种语言的控制结构是令人满意的。Bohm和Jacopini于1966

年在理论上证明,使用顺序、选择和重复就可对计算机所有可能的算法进行编码。因此,这3种结构组成了控制结构的有效集合。然而,仅仅使用这3种控制结构写出的程序不太直观。实际上,增加一些控制结构的表达方式(如:增加多重选择case,do-while,repeat-until等),虽然在理论上是多余的,但这样的确能提高程序的可写性和可读性。3.3单元级控制结构单元级控制结构:规定程序单元之间控制流程的机制38在程序顺序执行的过程中,遇到一个分程序,就建立一个新的引用环境,并执行这个分程序。更强的机制允许程序员通过显式调用单元(例如函数和过程),把控制从一个单元转移到另一个单元。四种单元级控制结构

显式调用从属单元异常处理协同程序并发单元这种类型的调用覆盖所有的子程序:

FORTRAN

语言的子程序和函数

PASCAL

语言的函数和过程

C语言的函数

…都属于显式调用。一.显式调用从属单元每个子程序(函数、过程)都有一个名字,通过名字进行程序单元的调用。执行调用语句时将控制转向被调用单元,被调用单元执行完后,又将控制返回主调用单元,并继续执行紧跟在调用语句后面的语句(返回地址)。子程序B子程序Areturn…callBendA返回地址当控制从调用单元转向被调用单元时,还可进行参数传递。参数传递可实现单元之间的通信。单元之间的通信也可以通过全局变量或非局部变量来进行(副作用)参数传递每次调用允许传递不同的数据(实际参数),为单元间的通信提供了灵活性。也提高了程序的可读性和可修改性。参数的两种绑定方式在大多数程序的子程序调用中,使用

位置对应方法实现实参与形参的绑定。subprogramS(Fl,F2

,…

,FN);

……子程序调用方式callS(Al,A2

,…

,AN);位置方法表示实参Ai绑定形参Fi位置参数绑定方式很方便。在参数比较多,又允许多个参数省略的情况下,很容易出错。设N=10,且第2,4,5,6,7,9个形参对应的实参都省略,那么callS(Al,,A3,,,,,A8,,A10)

很可能把逗号的位置弄错。多一个逗号或少一个逗号都会造成形参与实参的绑定错误,同时也降低了程序的可读性。为了克服上述缺点,有些语言显式列出相应实参与形参的绑定关系。callS(A1=>F1,A3=>F3,A8=>F8,A10=>F10)在参数可省略(缺省参数)的情况下,一般都要在过程(或函数)首部做出专门的规定:指出以什么样的特定值(缺省值)来替代省略的实参。C++的缺省参数intSHOW(char*s,intx=0,inty=0){…}在子程序调用中,

副作用和别名也会影响程序的可读性,容易导致程序出错。对非局部环境的修改①副作用降低了程序的可读性②副作用限制了数学运算律的使用如:w:=x+f(x,y)+z③副作用影响目标代码的优化如:u:=x+z+f(x,y)+f(x,y)+x+zx、y为变参z为全局变量3.副作用

534.别名在单元激活期间,两个变量表示(共享)同一数据对象对非局部环境的修改。①FORTRAN的EQUIVALENCE语句,EQUIVALENCE(A,B)②Pascal的变参使得形参和实参共享同一数据对象③C++的引用参数

54procedureswap(varx,y:integer);beginx:=x+y;y:=x-y;x:=x-y;end;

调用swap(a,a);swap(b[i],b[j]);若i=jswap(p,q);若p、q指向同一数据对象55voidswap(int&x,int&y){x:=x+y;y:=x-y;x:=x-y;}procedureswap(varx:integer);/*a是全局变量*/beginx:=x+a;a:=x-a;x:=x-a;end;调用swap(a);将产生不正确的结果③变参和全局变量表示同一数据对象时,也会引起别名

56④别名也影响编译器生成优化的代码

a:=(x-y*z)+w/*若a与x、y或z中任

b:=(x-y*z)+u

一个是别名*/

⑤别名的消除

.废除可能引起别名的结构

.限制使用指针、变参、全局变量、数组等

57二.隐式调用单元异常处理

隐式地将控制从一个单元转向到另一个单元,通常有于异常处理异常是指导致程序正常执行中止的事件,要靠发信号来引发,用异常条件来表示,并发出相应的信号,引发相应的程序。58早期语言中除PL/1外,通常没有专门的异常条件及异常处理程序。后期开发的语言提供了异常处理机制,使涉及异常事件的处理独立出来.

不包括在程序的主流程中,以保证程序的逻辑按基本算法进行。(1)异常如何说明,它的作用域是什么?(2)异常如何发生(或如何发信号)?(3)发出异常信号时,如何规定要执行的单元(异常处理程序)?(4)发出异常时,如何绑定相应的异常处理程序?(5)处理异常之后,控制流程转向何处?异常处理要考虑的问题

60在这些问题中,问题(5)的解决对语言处理异常机制的能力和可使用性有很大的影响。方法1语言设计中可能的基本选择是,相应的异常处理程序执行完之后,允许控制返回发生异常事件的执行点。在这种情况下,异常处理程序可对执行的程序进行“修补”,终止相应的异常事件,以便程序继续正常地执行。解决了程序继续执行的问题,但并未真正消除发生异常的因素。方法2相应的异常处理程序执行完之后,终止引起异常的程序单元的执行,由异常处理程序进行控制的转移。从概念上说,这意味着引起异常的单元不能恢复执行;从实现的观点来看,这意味着删除异常单元的活动记录。1.PL/1异常处理2.CLU的异常处理3.Ada的异常处理自学,了解。4.C语言的出错处理实现出错处理的方法是将用户函数与出错处理程序紧密地结合起来,但将造成出错处理使用的不方便和难以接受。用C标准库的assert宏进行出错处理使用allege函数在运行时检查错误。allege函数对一些小型程序很方便,对于复杂的大型程序,所编写的出错处理程序也将更加复杂。5.C++语言的异常处理异常处理是C++的一个主要特征,它提出了出错处理更加完美的方法。设置陷阱

抛出异常捕获异常

trythrowcatchC++的异常处理语句的格式如下:try{…}catch(异常类型1){异常1处理程序}catch(异常类型2){异常2处理程序}……catch(异常类型n){异常n处理程序}Try{

//可能发现异常的语句块}catch(异常类型,e){

//发生异常时候的执行语句块}

finnally{

//不管是否发生异常都执行的语句块}java异常处理

70三.

SIMULA67语言协同程序

定义:两个或两个以上程序单元之间交错地执行,这样的程序称为协同程序。例如:设有程序单元C1和C2,由C1开始执行,当执行到C1的“resumeC2”命令时,显示激活C2,并将C1的当前执行点的现场保存起来,将控制C2的执行点;若C2执行到某个“resumeC1”语句,将C2的当前执

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论