第三章过程式程序设计语言.ppt
《第三章过程式程序设计语言.ppt》由会员分享,可在线阅读,更多相关《第三章过程式程序设计语言.ppt(94页珍藏版)》请在三一办公上搜索。
1、第三章 过程式程序设计语言,基本观点:计算实现的模型如果按冯诺依曼原理强制改变内存中的值叫命令(或译指令、强制Imperative式)的。由于强制改变值,程序状态的变化没有一定规则,程序大了就很难查错,很难调试,不易证明其正确。组织程序的范型即:算法过程+数据结构(计算控制+计算对象)3.1 计算对象表示值与类型3.2 计算对象实现存储3.3 计算对象连接束定3.4 计算组织-程序控制3.5 计算组织-函数与过程3.6 计算组织-抽象与封装,类型是计算机可能实现的结构和约定对客观世界差异的刻划。同一类型的外延,即同一结构表示所有可能的值构成一个域。分类原则:同样表示结构,同样语义解释,同样的操
2、作。同类型值运算结果:同类型。无符号整数:二进制解释的值整数:符号 值,3.1 计算对象-值与类型,浮点数:符号 阶码 尾数,程序语言中:基元(primitive)类型:整型/实(定,浮)/字符/真值/枚举结构(structured)类型:元组/数组/记录(结构)/表/串,3.1.1 字面量、变量、常量,名字操纵值,名:字面量 从名字即知类型 字面值不变 变量 符号名要声明类型 值可变 常量 符号名要声明类型 值不变 基元值的名字是地址的别名,地址值在计算机中不恒定 操纵地址的名字是指针(地址变量)float*p,x=37.32;p=,(p)203C,(x)117F,117F,37.32,续,
3、名值可分导致 x=x+1;按名 按名取值:引用reference 存值 左值 右值 int x 既是右值也是左值,3.1.2 值是头等程序对象,程序语言中的值字面量(整、实、布尔、字符、枚举、串)复合量(记录、数组、元组、结构、表、联合、集合、文件)指针值变量引用(左值、右值)函数和过程抽象,数学对象参与运算的权利是一样的,值是计算对象也要按一致性原则:可出现在表达式中并求值可作函数返回值可单独存储 可以构成复杂的数据结构可作函数参数,3.1.3 类型系统,类型定义 值的集合和值上操作集合(V,Op)类型系统 一组可直接使用的类型类型规则类型检查机制,3.1.3 类型系统,静态与动态 静 动
4、变量 有类型 无类型 动态简洁、灵活 参数 有类型 无类型 静态清晰、死板 值 有类型 有类型弱/强类型无类型 LISP,Smalltalk弱类型 变量有类型。类型兼容性大,系统不作检查强制类型 隐式类型强制(转换),自动截尾,补零。显式 类型强制 PL/1伪强类型 静态均有类型且作检查,由于不严,导出等价准则 Pascal强类型 类型有严格定义,均作检查 Ada,类型等价 按结构等价 type A is array(range 1.100)of INTEGER;type B is array(range 1.100)of INTEGER;OA1,0A2:A;OB1,OB2:B;OC1:arr
5、ay(range 1.100)of INTEGER;OD1,OD2:array(range 1.100)of INTEGER;OE1:A;OA1,OA2,OB1,OB2,OC1,OD1,OD2,OE1均等价,续,按名等价 OA1,OA2 是同一类型(都用A声明)OA1,OB1,OC1是不同类型(类型名为A,B,无)OD1,OD2 是同一类型(同时声明,虽无名)OD1,OC1 是不同类型(两次声明)OA1,OE1 是同一类型(虽两次声明,但同名)类型完整性准则 涉及值的类型中不能随意限定操作,力求没有第二类的值,续,3.1.4 类型兼容,不同类型值混合运算,人为定出计算级别,由低 层升格为高层,
6、结果值是高层的隐式转换 弱类型 I:=R;显式转换 强类型 I:=Integer(R);强类型按名判定,不同类型名则不兼容只有子类型不同名可以兼容显式和隐式混合,type BASE is INTEGER;subtype SON_TYPE is BASE range 1.1000;-子类型type DIVERSE is new BASE range 1.1000;-派生类型A,B:BASE;C,D:SON_TYPE;E:DIVERSE;A:=B+C,-合法,结果为B类型赋给AA:=C+E;-不合法A:=C+SON_TYPE(E);-合法,有显式强制A:=E;-不合法,两个类型E:=B+BASE(
7、E);-不合法,续,3.2 计算对象的实现-存 储,存储对象是程序对象在计算机中的实现 程序对象不一一对应为存储对象 x:=0;x,0是两程序对象 只有一个存储对象x加指令清零 初值常量也不作为单独存储对象,3.2.1 程序变量的时空特性,引用和指针,P指针是地址变量*P是P所指的内容,也有左值和右值*P左值是P所指地址值,即P的值*P右值是所指地址内的内容值,引用是常指针是变量的别名,但实现是不一样的,递引用 dereference,通过指针变量引用变量的值为递引用*P1右值即递引用有些语言显式递引用算符如FORTH的,1 13 VARIABLE xx(声明变量xx并赋初值13)2 0 VA
8、RIABLE Y(声明变量Y并赋初值0)3 xx 2*Y!(相当于Y=xx*2)如果只写xx 2*则为将xx的地址乘以2放在Y之中,3.2.1 变量的时态,分配/未分配/除分配分配:为程序对象创建存储对象 编译时分配叫静态分配 allocate 运行时分配叫动态分配如声明指针p,执new才分配未分配:声明了未分配运行时分配除分配:取消存储对象(程序对象)delete操作显式自动除配:无用单元收集Garbage collection动态语言有,静态可有Ada可没有C,续,4,3,?,?,a b c d e f,声明和定义:定义必然声明;反之不然 声明的两个作用:给出对象,该对象的时间有效性 出了
9、声明的作用域该对象失去定义。在声明的作用 域内显式删除也失去定义,定义/未定义/失去定义 只要分配存储对象必然有残值,无意义即未定义 赋值或初值变量得以定义,a,b:分配且有定义c,d:分配未定义或失去定义e,f:未分配或除配,3.2.2 存储模型,基元类型值 仅除数组记录、构造、表 不可更新其中一元素函数抽象,ML重过程变量引用,可存储值Storable:指最小的可直接访问的可存储单元中的值Pascal可存储值:集合不选择更新某一元素是可存储值,Pascal,C,Ada数组可选择更新,不是可存储值。引用非可存储(C+可存储),过程和函数名也非可存储ML几乎都是可存储值,也带来毛病:每次更新结
10、构数据都要重来。它们是:,(if exp then sin else cos)(x)得sin(x)cos(x),可存储值,存储对象的生存期,全局变量 和引用程序寿命一样长局部变量 和程序中的一个模块寿命一样长持久变量 比程序寿命长除非显式撤销 文件变量瞬间变量(transient)持久变量的逆,每个存储对象都有创建(生),可用(活着),撤销(死)的生命期。按生命期长短分:,静态存储对象,编译时分配存储对象,近代语言类属对象直到装入后确立(elaboration)之时才定下存储对象叫静态分配 一旦执行不再改动其存储,直至所在存储单元无效叫静态(Static)存储对象 全局变量均为隐式的静态对象,
11、COBOL,BASIC全静态,ALGOL,C是显示声明静态,Pascal除全局,Ada 不能。C语言的静态变量是既私有又不随所在声明块中消逝,全局于所在文件。auto是静态分配动态装入不叫静态对象。Extern是静态对象。,extern,static,auto,动态存储对象,把寿命特长的(如文件,全局量)排出来归到栈底的某一组,把寿命特短的(如循环控制变量)另立嵌套组,这个问题也就解决。,块5,块66,块1,块2,块3,块4,5,4,6,6,5,4,6,寿命,动态存储对象,二叉树其大小由输入值定在运行中确立。内存开辟堆(heap)随生成随堆放动态存储对象。指针(即堆变量)所指程序对象用堆存放,
12、问题:多次重分,内存成了小洞 解决办法:按寿命分组寿命最长的放在较低(按其所在块生命期)。,重复使用,无法再分,堆栈帧管理,由动态堆栈联想到一般嵌套式语言可按动态堆栈式管理,多数变量和所在块寿命一样长(语言称之为自动变量),动态堆栈式存储 按程序动态执行,以动态堆栈管理局部数据和动态生成数据 运行时堆栈Run-time stack其底压入程序代码和全局,静态量。每执行到调用时生成一个堆栈帧(frame)记录该块数据信息,每当返回则局部量自动撤销对于递归块的局部量可多次生成多次消除。动态链描述调用父辈地址,返回地址是继续执行的下一地址。静态链描述词法父辈lexical parent块地址,按该块
13、复制局部变量。,参数,返回地址,动态链,静态链,返回值,局部变量,程序代码全局静态存储,首先调用块堆栈帧,第二调用块堆栈帧,最新调用块堆栈帧,临时变量空间,栈顶,堆栈帧组织,运行时堆栈,续,调用块首地址,本帧词法父辈,举例 求整数连乘积之递归程序:function product(jj:Integer):Integer;var kk:Integer;begin if jj=0 then product:=1 else begin readln(kk);product:=kk*product(jj-1)end end;,Product函数目标代码,jj:2return:?kk:25,jj:1re
14、turn:?kk:7,jj:0return:?kk:?,临时存储,DL,SL:静态链,DL:静态链,最初调用时堆栈帧,第一次调用时堆栈帧,第一次调用时堆栈帧,栈顶,SL,动态堆存储,忽略死对象 不超过一页浪费,若寿命差不多浪费不大保持一个自由表(链表)8个字节头说明数据按类型长度保持多个表减少识别域开销(Ada),动态堆栈缺点:开始帧不知有多大,要求存储对象比创建它的块寿命长。指针和显式动态分配依然不少了堆。按帧也设heap 各种语言堆分配 FORTH LISP C Pascal Ada分配 Here cons malloc new new除配 无回收 有回收 显式除 显式除 有回收 死堆对象
15、处理 死堆对象也叫无用单元garbage。(垃圾),3.2.3 悬挂引用Dangling Reference,当堆式管理同时提供显式除配命令KILL时;堆栈式管理外块指针指向内块对象时;函数抽象作为第一类值时,都会产生悬挂引用 解决办法 Pascal把指针限制为堆对象且不用dispose,不提供地址运算。操作数组不能按指针寻址,快速索引 C语言比较自由,悬挂引用留给程序员 局部函数作为返回值产生的悬挂指针。ML,Mirada完全作为堆变量且无KILL。Algol 68是引用(常指针),不赋比局部量寿命更长的值,例 悬挂引用(C)int*dangle(int*ppp)/参数是指针的指针 int
16、p=5;int m=21;*ppp=&p;/传回的指向p的指针 return&m;/返回m的地址main()int k=17;int*pm,*pk=&k;/pk指向k pm=dangle(&pk);/返回时pm,Pk均指向已/失去定义的指针函数的/局部量,即p和m,3.3 计算对象的连接-束定Binding,名字操纵程序对象。名字和存储对象联系起来才成为程序对象。把声明名字(地址)和存储对象或语义实体连接起来叫束定。束定 绑定 定连 连编(编译中连接模块)名字与束定 一名可束定到多个对象。一对象可以束定到多个名字。在一个程序的声明期内一旦束定不再改变叫静态(早)束定 运行中一个名字束定到(多个
17、)对象叫动态(晚)束定,3.3.1 静态束定,编译按数据类型为名字分配合适大小的存储对象,该对象首地址填入符号表即为静态束定,编译后变量表销毁,故静态束定不能变。,符号表 运行时内存,类型 名字 束定 存储对象,real length(地址),array1.4 of integer age(地址),多重束定 FORTRAN等价语句,以内部引用实现。Real P2,P3Dimension P1(3)Equivalence(P1,P2),(P1(2),P3),P1 P2 P3,其它语言多重束定是:COBOL REDEFINES Pascal 变体记录 C 联合,3.3.2 动态束定,运行时将名(字
18、)束定于其体(得 其语义操作)解释型语言一般保留名字表运行中束定。FORTH语言动态束定它是编译 解释型每当生成word出一字项,有两片代码 一为初始化和该名应执行的代码(编 译完成)。新字体中用到旧字,则运行中束定。解释执行另一片代码时,动态束定编译块。FORGET命令可以撤销当前字定义。,名字域(字),链接域,类型域,参数域(体),.,WORD,WORD,项,项,项,指前一字指针,执行堆栈,例 FORTH 的动态束定0:2by3array(:表示编译开始,后为类型声明符)1 create(编译动作:将类型声明符装入字典项)2 2,3(在字典项中存入 23维数)3 12 allot(为六个短
19、整数分配12个字节)4 does(运行时动作指令,取下标)5 rangecheck(函数调用,检查下标)6 if(如果不越界)7 linearsub(函数调用,计算线性下标值)8 then(给出数组基地址和位移)9;(;切换成解释执行,数据类型定义毕)10 11 2by3array box(声明并分配名为box的数组变量)12 10 1 2 box(给box(1,2)赋值10),3.3.3 无类型语言束定,名字 束定,length,age,符号表 运行时内存存储对象:类型标签,scalar number,array of 4 number,不同时刻可以将一名字束定到不同存储对象上。,APL语言
20、可显式操纵束定:束定符号 APL是无类型解释执行语言,以下是计算税金的程序:TAXCALC 1 ENTER GROSS PAY 2 GROSS/输入什么值GROSS就是 什么类型,表示终端输入。3 LESS GROSS 18000/条件表达式为真转 LESS标号句 4 TAX.25 GROSS/表达式结果值束定到TAX 5 DISPLAY/转到标号DISPLAY句 6 LESS:TAX.22 GROSS 7 DISPLAY:THE TAX IS$,TAX 8,3.3.4 声明declaration,声明指明本程序用到的所有程序对象给出所有束定集合 声明给翻译必要信息 声明的确立产生事实上的束定
21、 声明有显式的和隐式的 例:Ada的显式声明:基本声明:=对象|数|类型|子类型|包|子程序|任务|类属|异常|类属设例|换名|延迟Ada的隐式声明:块名字,循环名字,语句标号,循环控制变量,预定义运算符,声明种类,定义,为对象名提供完整的束定信息。声明可多次定义只次。定义是从已有信息定义新信息,Ada称之为rename。函数式语言,无类型语言只有值定义,没有变量声明。,val even=fn(n:int)=(n mod 2=0)函数型构 函数体 束定 函数定义 值定义 fun even(n:int)=(n mod 2=0)函数抽象 体,顺序声明的Ada例子,package MANAGER i
22、s-声明程序包规格说明 type PASSWORD is private;-声明私有类型未定义 NULL_PASSWORD:coustant PASSWORD;-立即用私有类型声明变量 function GET return PASSWORD;-返回私有类型函数 function IS_VALID(P:in PASSWORD)return BOOLEAN;Private type PASSWORD is range 0.700;-定义私有类型 NULL_PASSWORD:constant PASSWORD:=0;-此时才定义end MANAGER;,顺序与并行声明,声明是顺序的,声明后立即有用
23、,次序是重要的 D1;D2;D3/D2中可利用D1的声明,D3可利用D1,/D2的声明(见Ada例)并行声明D1D2它们一般相互独立,确立次序不影响语义 ML的例子:Val Pi=3.14159 and sin=fn(x:real)=(.)and cos=fn(x:real)=(.)and tan=fn(x:real)=sin(x)/con(x)非法 并行声明仅当声明语句结束,各并行子声明同时生效,递归声明 用声明定义自己的声明,D=D 直接递归。名字一样就是递归 D1=D2 间接递归,或相互递归 D2=D1 指明递归(ML)val rec power=fn(x:real,n:int)=if
24、n=0 then 1.0 else if n 0 then 1.0/power(x,-n)else x*power(x,n-1)如果没有rec两次power应用出现则调其它地方定义的power而不是本身,声明作用域,嵌套块与可见性标识符和全名,作用起始 顺序 每一子声明结束即起作用 并行 所有子声明结束才起作用 递归 只要遇见相同被声明符,就起作用,可见性Visiability指简单标识符可引用该对象。嵌套有复盖名字冲突,同样名字出现在嵌套块中,按最近声明解释。被覆盖的只能加块名前缀(称全名),如outer.x才可使用。C+用:作用域分辨符。,正因为有冲突所以内部束定时只能束定全名,A.x,B
25、.y,块声明,把一个语句扩大到块,封闭的块有局部声明 Begin D;C end;D是声明集,C是语句集。说明作用域只限于此块 块声明:含有局部声明的声明,子声明的束定用于声明。ML:local fun multiple(n:int,d:int)=(n mod d=0)/函数说明 in fun leap(y:int)=(multiple(y,4)/用于另一函数定义 andalso not multiple(y,1000)orelse multiple(y,400)end,3.3.5 束定作用域与释义,束定与环境 在束定集的作用范围内称环境(environment)。词法作用域 程序正文给出的嵌
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第三 程式 程序设计语言

链接地址:https://www.31ppt.com/p-5293902.html