收藏 分销(赏)

第三章过程式程序设计语言.ppt

上传人:快乐****生活 文档编号:14660280 上传时间:2026-10-26 格式:PPT 页数:94 大小:1.02MB 下载积分:10 金币
下载 相关
第三章过程式程序设计语言.ppt_第1页
第1页 / 共94页
第三章过程式程序设计语言.ppt_第2页
第2页 / 共94页


点击查看更多>>
资源描述
,单击此处编辑母版标题样式,单击此处编辑母版文本样式,第二级,第三级,第四级,第五级,*,第三章 过程式程序设计语言,基本观点:,计算实现的模型如果按冯,诺依曼原理强制改变内存中的值叫命令,(,或译指令、强制,Imperative,式,),的。由于强制改变值,程序状态的变化没有一定规则,程序大了就很难查错,很难调试,不易证明其正确。,组织程序的范型即,:,算法过程,+,数据结构(计算控制,+,计算对象),3.1,计算对象表示,值与类型,3.2,计算对象实现,存储,3.3,计算对象连接,束定,3.4,计算组织,-,程序控制,3.5,计算组织,-,函数与过程,3.6,计算组织,-,抽象与封装,类型是计算机可能实现的结构和约定对客观世界差异的刻划。,同一类型的外延,即同一结构表示所有可能的值构成一个域。,分类原则:同样表示结构,同样语义解释,同样的操作。,同类型值运算结果:同类型。,无符号整数:二进制解释的值,整数:符号 值,3.1 计算对象-值与类型,0,1,0,0,0,1,1,1,1,1,1,0,1,0,0,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,1,1,浮点数:符号 阶码 尾数,程序语言中:基元(,primitive),类型:整型/实,(定,浮)/字符/真值/枚举,结构(,structured,),类型:元组/数组/记录(结构)/表/串,3.1,.1,字面量、变量、常量,名字操纵值,名:字面量 从名字即知类型 字面值不变,变量 符号名要声明类型 值可变,常量 符号名要声明类型 值不变,基元值的名字是地址的别名,地址值在计算机中不恒定,操纵地址的名字是指针(地址变量),float *p,x=37.32;p=,(,p)203C,(,x)117F,117,F,37.32,续,名值可分导致,x =x +1,;,按名 按名取值:引用,reference,存值,左值 右值,int,&,Rint,=,Svar,Rint,是引用类型的变量,即左值变量必须给一右值,因 而成,Svar,别名,y=x+;,x,既是右值也是左值,3.1.,2,值是头等程序对象,程序语言中的值,字面量(整、实、布尔、字符、枚举、串),复合量(记录、数组、元组、结构、表、联合、集合、文件),指针值,变量引用(左值、右值),函数和过程抽象,数学对象参与运算的权利是一样的,值是计算对象也要按一致性原则:,可出现在表达式中并求值,可作函数返回值,可单独存储,可以构成复杂的数据结构,可作函数参数,类型等价,按结构等价,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:array(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,类型兼容,不同类型值混合运算,人为定出计算级别,由低 层升格为高层,结果值是高层的,隐式转换 弱类型,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,类型赋给,A,A:=C+E;-,不合法,A:=C+SON_TYPE(E);-,合法,有显式强制,A:=E;-,不合法,两个类型,E:=B+BASE(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,VARIABLE 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,声明和定义:定义必然声明;反之不然,声明的两个作用:给出对象,该对象的时间有效性,出了声明的作用域该对象失去定义。在声明的作用,域内显式删除也失去定义,定义/未定义/失去定义,只要分配存储对象必然有残值,无意义即未定义 赋值或初值变量得以定义,a,b:,分配且有定义,c,d:,分配未定义或失去定义,e,f:,未分配或除配,3.2.2 存储模型,基元类型值 仅除数组,记录、构造、表 不可更新其中一元素,函数抽象,ML,重过程,变量引用,可存储值,Storable:,指最小的可直接访问的可存储单元中的值,Pascal,可存储值:集合不选择更新某一元素是可存储值,,Pascal,C ,Ada,数组可选择更新,不是可存储值。,引用非可存储(,C+,可存储),过程和函数名也非可存储,ML,几乎都是可存储值,也带来毛病:每次更新结构数据都要重来。它们是:,(,if exp then sin,else cos)(x),得,sin(x)cos(x),可存储值,存储对象的生存期,全局变量 和引用程序寿命一样长,局部变量 和程序中的一个模块寿命一样长,持久变量 比程序寿命长除非显式撤销 文件变量,瞬间变量(,transient),持久变量的逆,每个存储对象都有创建(生),可用(活着),撤销(死)的生命期。按生命期长短分:,静态存储对象,编译时分配存储对象,近代语言类属对象直到装入后确立,(,elaboration),之时才定下存储对象叫静态分配,一旦执行不再改动其存储,直至所在存储单元无效叫静态(,Static),存储对象,全局变量均为隐式的静态对象,COBOL,BASIC,全,静态,ALGOL,C是显示声明静态,P,ascal,除全局,A,da,不能。,C,语言的静态变量是既私有又不随所在声明块中消逝,全局于所在文件。,auto,是静态分配动态装入不叫静态对象。,Extern,是静态对象。,extern,static,auto,动态存储对象,把寿命特长的(如文件,全局量)排出来归到栈底的某一组,把寿命特,短的(如循环控制变量)另立嵌套组,这个问题也就解决。,块5,块6,6,块1,块2,块3,块4,5,4,6,6,5,4,6,寿,命,动态存储对象,二叉树其大小由输入值定在运行中确立。内存开辟堆(,heap),随生成随堆放动态存储对象。指针(即堆变量)所指程序对象用堆存放,问题:多次重分,内存成了小洞,解决办法:按寿命分组寿命最长的放在较低(按其所在块生命期)。,重复使用,无法再分,堆栈帧管理,由动态堆栈联想到一般嵌套式语言可按动态堆栈式管理,多数变量和所在块寿命一样长(语言称之为自动变量),动态堆栈式存储,按程序动态执行,以动态堆栈管理局部数据和动态生成数据,运行时堆栈,Run-time stack,其底压入程序代码和全局,静态量。每执行到调用时生成一个堆栈帧(,frame),记录该块数据信息,每当返回则局部量自动撤销对于递归块的局部量可多次生成多次消除。,动态链描述调用父辈地址,返回地址是继续执行的下一地址。,静态链描述词法父辈,lexical parent,块地址,按该块复制局部变量。,参数,返回地址,动态链,静态链,返回值,局部变量,程序代码,全局静态存储,首先调用块,堆栈帧,第二调用块,堆栈帧,最新,调用块,堆栈帧,临时变量空间,栈顶,堆栈帧,组织,运行时堆栈,续,调,用,块,首,地,址,本,帧,词,法,父,辈,举例,求整数连乘积之递归程序:,function product(,jj,:Integer):Integer;,var,kk,:Integer;,begin,if,jj,(,运行时动作指令,取下标),5,rangecheck (,函数调用,检查下标),6,if (,如果不越界),7,linearsub (,函数调用,计算线性下标值),8,then (,给出数组基地址和位移),9 ;(;切换成解释执行,数据类型定义毕),10,11 2,by3array box (,声明并分配名为,box,的数组变量),12 10 1 2,box (,给,box(1,2),赋值10),3.3.3,无类型语言束定,名字 束定,length,age,符号表 运行时内存存储对象:类型标签,scalar number,array of 4 number,不同时刻可以将一名字束定到不同存储对象上。,APL,语言可显式操纵束定:束定符号,APL,是无类型解释执行语言,以下是计算税金的程序:,TAXCALC,1 ENTER GROSS PAY,2 GROSS /,输入什么值,GROSS,就是 什么类型,表示终端输入。,3 ,LESS GROSS (n mod 2=0),函数型构 函数体,束定,函数定义,值定义,fun even(n:int)=(n mod 2=0),函数抽象 体,顺序声明的,Ada,例子,package MANAGER is -,声明程序包规格说明,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;,顺序与并行声明,声明是顺序的,声明后立即有用,次序是重要的,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 n=0 then 1.0,else if n S1;case v1:S1;,when v2=S2;break;,.case v2:S2;,when vm|vn=Sn;break;,when others=St;default:St;,end case;next;,执行一个,Si,跳到,end case,没有,break,要顺序执行,直到,next,e1,e2,e3,S1,S2,S3,C,以条件表达式实现选择控制,a=bc?b:c if(bc)a=b,;,else a=c;,条件表达式 条件语句,命令式语言大量依赖顺序命令,纯函数式语言完全依赖写嵌套函数调用。,迭代控制,迭代一般用于处理同构的、聚集数据结构的重复操作,诸如数组、表、文件。,显式迭代,(循环),显示迭代有以下几种:,无限循环,有限循环的三种形式,:,while_do,do_until,do_while_do,FORTRAN,初始 上界 增量,DO L I=EXP1,EXP2,EXP3,Ada,for BACKDAY in reverse DAY RANGE loop,在循环控制变量和表达式约定上几十年来一直在演变,C,采用,迭代元素(,Iteration element),iterate()=,iterate(;),对迭代元素不加任何限制。语句,表达式,连续赋值,空,均可。先算,再算,若不为零,,则算,然后执行,。若为零出口。若不为零再算,,若不为零重复以上步骤,若为零则出循环。,计数循环,例,:,用,for,循环计算表中元素之和,设表,list,是一简单结构,一个成分是值,value,,,另一个成分是指向下一表元素的指针,next,。,可以有以下六种写法:,1 先赋,sum,初值进入正规,for,循环:,sum=0;,sum+=current-value;,for(current=list;current!=NULL;,current=current-next),sum+=current-value,/,循环控制变量,current,就用表,list,2 sum,在循环内赋初值:,for(current=list,sum=0;current!=NULL;,current=current-next),sum+=current-value,3,循环控制变量可以在,for,以外赋初值,增量在体内赋值:,current=list,sum=0;,for(;current!=NULL;),sum+=current-value,current=current-next;,/,用,号连接的两语句成为一个命令表达式,4 循环条件为空,用条件表达式完成:,current=list,sum=0;,for(;),if(current=NULL)break;,else sum+=current-value,current-next;,/,不提倡此种风格,5 完全不用循环体,全部在循环条件中完成,for(current=list,sum=0;,(current=current-next)!=NULL;,sum+=current-value);,/,效率最高.但,list,不能为,NULL,表,6 逻辑混乱,也能正确计算:,current=list,sum=0;,for(;current=current-next;sum+=current-value),if(current=NULL)break;,/,最坏的风格,,,list,也不能为,NULL,表,3.4.2,异常处理,程序无法执行下去,也就是出现了异常(,exception),情况。在早期语言的程序中,出现了这种情况就中断程序的执行,交由操作系统的运行程序处理。现在向用户开放,,Ada,C+,Java,定义,用户定义,:,:,exception;,系统定义,的异常,(,Ada,):,CONSTRAINT_ERROR,凡取值超出指定范围叫约束异常,NUMBER_ERROR,数值运算结果值实现已不能表达,叫数值异常,STORAGE_ERROR,动态存储分配不够时,,,叫存储异常,异常定义,与处理段,TASKING_ERROR,任务通信期间发生的异常叫任务异常。,PROGRAM_ERROR,除上四种而外程序中发生的一切异常,,都叫程序异常.如子程序未确立就调用等。,预定义的可以显式也可以隐式引发,而用户定义的异常必须 显式引发,引发语句,:,raise;,引发语句可出现在任何可执行语句所在的地方。一旦引发,则本程序块挂起转而执行本块异常处理段中同名的异常处理程序。,每个程序块都可以在该块末尾设立异常处理段:,declare:,;,begin:,;,exception:,when=-,异常处理段,when,。,-,一般再次引发原异常(缺省名字),end;,Java,的异常处理语句,,try_catch_finally:,try/,可能有异常语句组,/,用,throw,显式抛出异常,/,也可以隐式自动抛出异常,catch(),/,异常处理段,-1,/catch,(捕捉),try,中抛出的异常对象,/,不匹配则跳过本,catch,不执行,catch(),/,异常对象段,-2,/,匹配执行后跳过所有,catch,finally/,善后处理段,/,只要进入,try,块,本段必须执行,/C+,无此机制,其余同,Ada,的嵌套异常及异常传播,的,with TEXT_IO,MATH_FUNCTIONS;,use TEXT_IO,MATH_FUNCTIONS;,procedure ONE_CIRCLE(DIAM:Float)is,RADIUS,CIRCUMFERENCE,AREA:Float;,begin,CIRCUMFERENCE:=DIAM*22.0/7.0;,RADIUS:=DIAM/2.0;,AREA:=RADIUS*RADIUS*22.0/7.0;,PRINT_CIRCLE(DIAM,RADIUS,CIRCUMFERENCE,AREA);,7 exception,when NUMBER_ERROR=,raise;,end ONE_CIRCLE;,procedure CIRCLES is,DIAMETER:Float;,MAXIMUM:constant Float:=1.0e6;,0TOO_BIG_ERROR:exception;,PUT(please enter an float diameter.);,begin,1loop,begin,GET(DIAMETER);,if DIAMETER MAXIMUM then,2 raise TOO_BIG_ERROR;,else,3 exit when DIAMETER,PUT(Diameter too large!please reenter.);,5end;,6end loop;,PUT(“processing finished.”);,PUT New_line;,end CIRCLE;,3.5,函数和过程,命令式语言中子程序有两种形式:函数(必须返回值),也叫函数,,过程(实施一组动作),也叫,子例程,subroutine,。,它们是程序的第一次分割,,,这种分割的好处:,实施的功能单一,便于调试;,相对独立,便于多人分工完成,且时间不受约束;,相对封闭,人们易于控制,是分解复杂性的有力措施。,子程序和主程序联系的接口特别重要。在这个界面上要指出该例程的数据特征,即输入什么输出什么。而整个子程序体是完成从输入到输出的实现手段。,界面指出“做什么?”,,,而子程序体回答“怎么做”。,80年代程序完成第二次分割:将子程序定义(即界面)和子程序体显式的分开,成为相对独立的规格说明(,Specification),和体(,body),。,3.5.1,函数和过程抽象,函数抽象是用一个简单的名字抽象代表一个函数。函数由函数型构(,Signature),和函数体(,body),组成。函数计算的目的是求值。函数体等同于一个复合的表达式。,函数抽象是对表达式的抽象,过程抽象是用一个简单的名字抽象代表一个计算过程。过程由过程型构和过程体组成。过程调用的目的是执行一组命令,过程抽象是对命令(即语句)集的抽象,函数由函数型构和函数体组成。形式是:,function FUNC(fp1,fp2,.),:,returntype,;,/,函数型构,B;/,函数体,可包括任何声明和语句,其中,fp1,,,fp2,,,为形式参数,也叫形式变元(,argument),returntype,为函数返回值的类型,函数引用是应用函数的唯一手段,它在同名的函数名之下给出实,在参数(实,在,变元):,FUNC(ap1,ap2,.);,各种语言函数定义,(a)FORTRAN,INTEGER FUNCTION FACT(N)/,前缀指明返回类型,INTEGER N,I,F /,参数类型在此声明,F=1,DO 10 I=2,N,F=F*1,10 CONTINUE,FACT =F /,必须至少定义函数名一次,RETURN /,至少有一返回语句,END,(b)Pascal,FUNCTION fact(n:Integer):Integer,;,/,参数类型在变元表中定义,,,BEGIN,/,后缀指明返回类型,fact=1,;,IF n=1 OR n=0 THEN,Return,ELSE,Fact=n*fact(n-1),;,/,也要定义,函,数名,END,(c)C,int fact(n)/,前缀指明返回类型,int n;/,参数在体中声名类型,int i,f;/ANSI C,改参数原型,f=1;,if(n1),for(i=2;i /,用,函数定义值,if n=1 then 1 else n*fact(n-1),续,多重入口和指定返回,FORTRAN,的多重入口示例,SUBROUTINE DEG(R,THETA,X,Y),C=3.14159/180.0,THETA=C*THETA,ENTRY RAD(R,THETA,X,Y),X=R*COS(THETA),Y=R*SIN(THETA),RETURN,END,若,THETA,是度数值时,则调用语句为:,CALL DEG(R,THETA,X,Y),/,入口在子程序顶部,若,THETA,是弧度值时,则:,CALL RAD,(,R,,,THERA,,,X,,,Y,),/,入口在子程序中,FORTRAN,的指定返回,SUBROUTINE RM,(,X,,,Y,,*,*,*),.,.,.,RETURN2/,返回语句标号80,.,.,.,RETURN1/,返回语句标号70,.,.,.,RETURN3/,返回语句标号120,.,.,.,END,CALL RM(A,B,70,80,120),形实参数表中元素个数,次序,类型应一致。早期语言都严格遵此准则。近代语言提供了较多的灵活表示法。,Ada,引入缺省参数,实参个数可少于形参个数,;,指明参数结合不考虑次序,;,Ada,引入参数模式,in,out,inout,指明只读,只写,读写参数。,C,语言允许任意多个参数的调用。如内定义函数,printf(),调用时可以写任意个输出,只是第一参数中的格式个数与参数个数对应。,过程定义与调用,过程子程序定义形式,procedure PROC(fp1,fp2,.)/,过程型构,B;/,子程序体包含局声明,对应的过程调用是:,PROC(ap1,ap2,.),;,C,语言一切过程,包括主程序都是函数过程。它以,void(,无值)关键字代替函数类型指明符,实施子程序过程语义,引用或调用的形式,无参过程,-,函数和过程的参数表均可为空。有的语言保留(),有的只有一个名字。一般无参过程也要更新过程内部的值。函数过程还会返回不同的值。全局量在函数中有效。改变了全局量两次调用结果值当然不一样。这就是函数的副作用(,side effect),。,-,有副作用的函数,C,在很大程度上利用函数副作用,例如,当需要跳过空白时写:,while(c=getch()=),;,-Ada,中常用的随机数:,function RANDOM return FLOAT range 0.01.0;,引用时,若,FIELD,已声明为常量:,RESULT=RANDOM*FIELD,;,RANDOM,若无副作用,RESULT,值不可能改变。,3.5.2,参数机制,语言中第一类对象均可作函数/过程参数。,由于变量的时空特性,传递的形-实参数可以有许多不同的实现结合的办法,,,即参数机制。,传值调用(,call-by-value,),1实参表达式先求值,2将值复制给对应的形参。形参和实参有同样大小的存储,3,过,程运行后一般不再将改变了的形参值复制回实参,Pascal,中的传值调用,PROCEDURE test1(J2,A2:Integer;P2:list),BEGIN,Writeln(J2,A2,P2.value);,J2=J2+1;,P2=P2.next;,Writeln(J2,A2,P2.value),END.,调用程序有:,test1(J1,A1J1,P1.next);,第一次打印为:,1 30%,第二次打印为:,2 30$,传名调用(,call-by-name),传名在过程/函数中加工的就是实参已分配的值,因此不需付出双倍存储代价。但传名过程,的,虚实结合,是,将程序体中所有形参出现的地方均以实参变元名置换。这样出现几次算几次效率是低的。,传名调用程序示例,由于,Pascal,无传名机制,此处作一点扩充:,PROCEDURE test2(NAME J2,A2:Integer;NAME P2:List);,函数体同,test1,执行同样调用:,test2(J1,A1J1,P1.next);,名结合后打印:,1 30%,执行后结果是:,2 45$,引用调用,(,call_by_reference),引用参数实现时,编译器在子程序堆栈中设许多中间指针,将形参名束定于此指针,而该指针的值是实参变量的地址(在主程序堆栈框架内),在子程序中每次对形参变量的存取都是自动地递引用到实参存储对象上。,引用调用的,Pascal,示例:,PROCEDURE test3(VAR J2,A2:Integer;VAR P2:List);,函数体同,test1,相应的调用程序是:,test3(J1,A1J1,P1.next);,第一次打印是:,1 30%,第二次打印是:,2 30$,引用调用图示,参数模式与返回调用(,call-by-return),显式指明参数传递模式,可以为编译实现提供信息,fun_name(x,y:Real;VAR s,q:Integer).,x,,,y,传值实现,它只读。,s,,,q,引用实现,可读/写,Ada,只规定参数模式,in,,,out,,,inout,,,传递方向的模式(,mode),。,由编译选择实现方式:,proc_name(X,,,Y:in Real;S:inout Integer;Q:outInteger),in,模式可不写出(缺省)。函数只能有,in,的模式,过程都有,且出现次序不受限制。,x,,,y,因在子程序中只读,传值实现可保证不受破坏。,s,读/写用引用实现,而,q,是只写参数,传值和引用都不能保证”只”写,实现返回调用机制有两种办法:其一是复制。另一种办法是引用实现增加”只写”保护,值-返回调用(,call-by-value-and-return,),是对,by-reference,的改进,因多进程竞争数据资源时多重引用(束定)易于引起混乱,P2,返回值由,P2,定 返回值由,P1,定,正,常顺序执行,对于并发多任务宜只读只写,值与返回调用机制是把值调用和返回调用组合起来,实现调用程序双向通道,这对于有多个存储器的多处理器系统和网络分布式系统值调用极度安全,在子程序执行期间因不是束定,形参变量的值不会中途改变,复制回去和拷贝进来处可设断点检查,P1,P2,P1,P2,P1,P2,指针参数(,call_by_point,),指针作为参数其实现方式一般是复制机制,它复制的是地址(指针内容),注意,和引用调用之同异,例:指针,Pascal,引用版:交换两变量的内容,PROCEDURE swap1(VAR a,b:Integer),;,VAR t:Integer;,BEGIN,T=a;a=b;b=t,END;,调用程序片断:,j=3;k=5;,swap1(j,k);/,结果,j=5,,,k=3,J=,3,K=,5,Caller-frame,=a,=t,=b,3,=,=,Swapl-frame,指针版,:,变换两变量的内容,TYPE,int_ptr=Integer;,VAR jp,kp:int_ptr;,PROCEDURE swap2(a,b:int_ptr);,VAR t:Integer;,BEGIN,t=a;a=b;,b=t,END;,相应调用程序片断:,NEW(jp);jp=3;,NEW,(,kp);kp=5;,Swap2(jp,kp);,C,语言的指针参数传递,void swap3(int*a,int*b),int t;,t=*a;*a=*b;*b=t;,形参是两指针,实参不用指针的版本:,main(),int j=3;k=5;,/,声明并初始化两整数,swap3(,/,类型匹配吗?,3.6,抽象与封装,函数和过程是封装的程序实体,它有数据和操作,,,规格,说明(,型构,),和过程体,,一体使于人们控制复杂性,Pascal,统一的嵌套结构不造于大型程序,数据,2,sub1-,sub10,数据,4,sub22,-sub28,数据,1,sub11-,sub15,数据,3,sub16,-sub21,main,续,将相关的数据和操作封装成大模块(若干类型,若干过程,/,函数)结构上形成包,package,或模块,Modula,包是可分别编译。随时连接软件资源,是解决复杂系统的有力手段,包的规格说明和包体显式分开。语义上正好是,“,作什麽,”,,,“,怎麽做,”,3.6.1,模块和包,规格说明和体在表示结构上的分离。有利于修改,维护,封装实现数据隐藏,有利于安全,规格说明是程序包的抽象,有利于复杂系统简化,模块,(,包,),封装数据与操作,它有可控界面,外界不能操纵私有数据引出公有,(,public,包的使用者可见),、私有,(,private,本包所有操作可访问,包外不可见),、保护,(,protected,包外不可见,但本包的子包可见),概念,包只是,以封装手段,可,有,/,可没有,逻辑,语,义,-只有数据无操作,数据块,BLOCK DATA(FORTRAN),-,只有操作无共享数据如函数包,数,学,库,-有数据有操作,,,一口对外可模拟自动机,-有数据有操作,,,模拟客观世界对象增加程序表达能力,-封装的包可实现复杂的数据类型,ADT,Ada,的复数程序包,package COMPLEX is,type NUMBER is record,REAL_PART:FLOAT,;,IMAG_PART:FLOAT,;,end record;,function+(A,,,B:in NUMBER)return NUMBER,;,function-(A,,,B:in NUMBER)return NUMBER,;,function*(A,,,B:in NUMBER)return NUMBER,;,end COMPLEX,;,package body COMPLEX is,endCOMPLEX;,有了这个程序包我们可以编出复数应用程序:,with COMPLEX,;,use COMPLEX,;,procedure MAIN is,COMP_1:NUMBER=(1.0,,,2.0),;,-1+2i,COMP_2:NUMBER:=(3.0,,,4.0),;,-3+4i,W,,,X,,,Z:NUMBER,;,begin,W=COMP_1+COMP_2,;,-W=4+6i,X=COMP_2-COMP_1,;,-X=2+6i,Z=COMP_1*COMP_2,;,-Z=-5+10i,end MAIN,;,3.6.2,抽象数据类型,数据抽象,数据抽象是抽象数据类型的方法学,定义一组数据集,V,,以及其上的操作集,Op,,构成,ADT(A,bstract Data Type,),T=(V,Op),-,什么和怎么做分开,(规格说明和体),-,实现数据隐藏(体中声明的数据和操作外界不可见),-,分别开发分别编译(可做大程序),-,简化复杂性便于调试(利用抽象实现分治),-,构造新类型,计算直观方便(面向对象的基础),构造新类型,Swith COMPLEY use COMPLEY;,Procedure MAIN is,C1:NUMBER is =(1.0,2.0);,C2:NUMBER is =(3.0,4.0);,W ,X,Z:NUMBER;,begin,W:=C1+C2;,X:=C2-C1;,Z:=C1*C2;,end MAIN,-,*,+,Number,LEX,COMP,构造函数和析构函数,变量,类型,V:integer,;以类型指明程序对象,变量抽象数据类型,声明时要指明如何构造,C,:,NUMBER,:,=,(,1.0,2.0),较简单可用赋初值办法,复杂在运行中由构造函数(,constructor),完成,C=ADT_Name(),构造函数(,constructor),和,ADT,同名,不再使用的程序对象,用析构函数(,destructor),显式删除,一般形式是:,ADT_Name(),和,ADT,同名,ADT_Name(),C,语言以文件实现抽象数据类型,C,语言4种文件,-,头文件“,modules.h”,定义宏和类型声明,-,主模块“,name.c”,给出新类型的数据和操作定义,-,其它模块“,other.c”,实现头文件中声明,-,通过,makefile,指明各文件关系,make SOMETYPE,SOMETYPE:name.o other.o /,连续两模块的目标码,文件取名,SOMETYPE,CC_o SOMETYPE name.o other.o/,编译并连成为,SOMETYPE,的目标文件,name.o:name.c modules.h/,两源文件连成为,name.o,CC_o name.o name.c /,源文件编译后形成目标文件,other.o:other.c modules.h,CC_o other.o other.c /SOMETYPE,如预定义的了,3.6.3,类属,函数是表达式集的抽象、过程是命令集的抽象,类属(,generic),是声明集的抽象。,即,声明的变量、类型、子程序都是参数化的。,Ada,类属子程序,:,generic,type ELEMENT is pravite,;,-,类属类型参数,procedure EXCHANGE(FIRST,,,SECOND,:,in out ELEMENT),;,TEMP,:,ELEMENT,;,-,程序中用类属形参,begin,TEMP=FIRST,;,FIRST=SECOND,;,SECOND=FIRST,;,end EXCHANGE,;,关键字,procedure,换成,package,即为类属包,参数化类型与实际类型结合。由类属设例指明:,procedure INT_EXCHANGE is new EXCHANGE(Integer),;,实在,的,Integer,与,ELEMENT,匹配,即在,procedure,中任何出现,ELEMENT,的地方以,Integer,代,,等于有了整数的,EXCHANGE,如,同,样板,,,可以写出多个过程:,procedure CHAR_EXCHANGE is new EXCH
展开阅读全文

开通  VIP、SVIP  下载更划算
下载10份以上建议开通 VIP 会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        关注我们

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服