




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第三章 过程式程序设计言语根本观念: 计算实现的模型假设按冯诺依曼原理强迫改动内存中的值叫命令(或译指令、强迫Imperative式)的。由于强迫改动值,程序形状的变化没有一定规那么,程序大了就很难查错,很难调试,不易证明其正确。 组织程序的范型即:算法过程+数据构造计算控制+计算对象3.1 计算对象表示值与类型3.2 计算对象实现存储3.3 计算对象衔接束定3.4 计算组织-程序控制3.5 计算组织-函数与过程3.6 计算组织-笼统与封装类型是计算机能够实现的构造和商定对客观世界差别的刻划。同一类型的外延,即同一构造表示一切能够的值构成一个域。分类原那么:同样表示构造,同样语义解释,同样的操
2、作。 同类型值运算结果:同类型。无符号整数: 二进制解释的值整数:符号 值 3.1 计算对象-值与类型0 10 0 0 1 1 11 11 0 1 0 0 0 1 0 1 0 1 00 0 0 0 1 0 1 0 1 0 1 1 浮点数: 符号 阶码 尾数程序文语中:基元(primitive)类型:整型/实定,浮/字符/真值/枚举构造structured类型:元组/数组/记录构造/表/串3.1.1 字面量、变量、常量 名字支配值, 名: 字面量 从名字即知类型 字面值不变 变量 符号名要声明类型 值可变 常量 符号名要声明类型 值不变 基元值的名字是地址的别名, 地址值在计算机中不恒定 支配地
3、址的名字是指针(地址变量) float *p, x = 37.32; p=&x; (p)203C(x)117F117F37.32续名值可分导致 x = x + 1; 按名 按名取值: 援用reference 存值 左值 右值 int & Rint = Svar Rint 是援用类型的变量,即左值变量必需给一右值,因 而成Svar别名 y = x + ; x 既是右值也是左值3.1.2 值是头等程序对象程序文语中的值字面量(整、实、布尔、字符、枚举、串)复合量(记录、数组、元组、构造、表、结合、集合、文件)指针值变量援用(左值、右值)函数和过程笼统,数学对象参与运算的权益是一样的
4、,值是计算对象也要按一致性原那么:可出如今表达式中并求值可作函数前往值可单独存储 可以构成复杂的数据构造可作函数参数3.1.3 类型系统类型定义 值的集合和值上操作集合V,Op)类型系统 一组可直接运用的类型类型规那么类型检查机制3.1.3 类型系统 静态与动态 静 动 变量 有类型 无类型 动态简约、灵敏 参数 有类型 无类型 静态明晰、死板 值 有类型 有类型 弱/强类型 无类型 LISP , Smalltalk 弱类型 变量有类型。类型兼容性大, 系统不作检查 强迫类型 隐式类型强迫转换,自动截尾, 补零。显式 类型强迫 PL/1 伪强类型 静态均有类型且作检查,由于不严,导出等价准那么
5、 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: 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声
6、明) OA1, OB1, OC1是不同类型(类型名为A,B, 无) OD1, OD2 是同一类型(同时声明, 虽无名) OD1, OC1 是不同类型(两次声明) OA1, OE1 是同一类型(虽两次声明, 但同名) 类型完好性准那么 涉及值的类型中不能随意限定操作, 力求没有第二类的值续3.1.4 类型兼容 不同类型值混合运算, 人为定出计算级别,由低 层升格为高层, 结果值是高层的 隐式转换 弱类型 I := R; 显式转换 强类型 I := Integer(R); 强类型按名断定,不同类型名那么不兼容只需子类型不同名可以兼容 显式和隐式混合type BASE is INTEGER; sub
7、type 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(E); -不合法续3.2 3.2 计算对象的实现计算对象的实现- - 存存 储储 存储对象是程序对象在计算机中的实现存储对象是程序对象在计算机中的实现 程序对象不一一
8、对应为存储对象程序对象不一一对应为存储对象 x:=0; x,0是两程序对象是两程序对象 只需一个存储对象只需一个存储对象x加指令清零加指令清零 初值常量也不作为单独存储对象初值常量也不作为单独存储对象3.2.1 3.2.1 程序变量的时空特性程序变量的时空特性援用和指针援用和指针P指针是地址变量指针是地址变量 *P是是P所指的内容所指的内容, 也有左值和右值也有左值和右值 *P左值是左值是P所指地址值,即所指地址值,即P的值的值 *P右值是所指地址内的内容值右值是所指地址内的内容值136140144A AB BC C3 31 12 23 31 16 63 32 20 0136140144( (
9、R RA A) )3 31 12 2( (R RB B) )3 31 16 6( (R RC C) )3 32 20 0136144( (p p1 1) )4 44 48 8( (p p2 2) )4 45 50 04274.543312.27607.01( (A A) )1 13 36 6( (B B) )1 14 40 0( (C C) )1 14 44 4援用是常指针是变量的别名援用是常指针是变量的别名, 但实现是不一样的但实现是不一样的递援用递援用 dereference dereference经过指针变量援用变量的值为递援用经过指针变量援用变量的值为递援用*P1右值即递援用右值即递援
10、用有些言语显式递援用算符如有些言语显式递援用算符如FORTH的的1 13 VARIABLE xx (1 13 VARIABLE xx (声明变量声明变量xxxx并赋初值并赋初值13)13)2 0 VARIABLE Y (2 0 VARIABLE Y (声明变量声明变量Y Y并赋初值并赋初值0) 0) 3 xx 2 3 xx 2 * * Y ! ( Y ! (相当于相当于Y=xxY=xx* *2)2)假设只写假设只写xx 2 xx 2 * * 那么为将那么为将xxxx的地址乘以的地址乘以2 2放在放在Y Y之中之中3.2.1 变量的时态变量的时态 分配分配/未分配未分配/除分配除分配 分配分配:
11、 为程序对象创建为程序对象创建存储对象存储对象 编译时分配叫静态分配编译时分配叫静态分配 allocate 运转时分配叫动态分配如声明指针运转时分配叫动态分配如声明指针p, 执执new才分配才分配 未分配未分配: 声明了未分配运转时分配声明了未分配运转时分配 除分配除分配: 取消存储对象取消存储对象(程序对象程序对象) delete操作显式操作显式 自动除配自动除配: 无用单元搜集无用单元搜集Garbage collection 动态言语有,静态可有动态言语有,静态可有Ada可没有可没有C续续43? ? a b c d e f 声明和定义:定义必然声明;反之不然声明和定义:定义必然声明;反之不
12、然 声明的两个作用声明的两个作用 :给出对象:给出对象, 该对象的时间有效性该对象的时间有效性 出了声明的作用域该对象失去定义。在声明的作用出了声明的作用域该对象失去定义。在声明的作用 域内显式删除也失去定义域内显式删除也失去定义定义定义/ /未定义未定义/ /失去定义失去定义 只需分配存储对象必然有残值只需分配存储对象必然有残值, , 无意义即未定无意义即未定义义 赋值或初值变量得以定义赋值或初值变量得以定义a,b:分配且有定义分配且有定义c,d:分配未定义或失去定义分配未定义或失去定义e,f:未分配或除配未分配或除配3.2.2 存储模型 基元类型值基元类型值 仅除数组仅除数组 记录、构造、
13、表记录、构造、表 不可更新其中一元素不可更新其中一元素 函数笼统函数笼统, ML重过程重过程 变量援用变量援用可存储值可存储值StorableStorable:指最小的可直接访问的可存储单元中的值:指最小的可直接访问的可存储单元中的值PascalPascal可存储值可存储值: :集合不选择更新某一元素是可存储值,集合不选择更新某一元素是可存储值,Pascal, C Pascal, C ,AdaAda数组可选择更新数组可选择更新, , 不是可存储值。不是可存储值。援用非可存储援用非可存储(C+(C+可存储可存储), ), 过程和函数名也非可存储过程和函数名也非可存储MLML几乎都是可存储值几乎都
14、是可存储值, , 也带来缺陷:每次更新构造数据都要重也带来缺陷:每次更新构造数据都要重来。它们是:来。它们是:( if exp then sin else cos ) (x) 得得sin(x)cos(x)可存储值可存储值 存储对象的生存期存储对象的生存期 全局变量全局变量 和援用程序寿命一样长和援用程序寿命一样长 部分变量部分变量 和程序中的一个模块寿命一样长和程序中的一个模块寿命一样长 耐久变量耐久变量 比程序寿命长除非显式撤销比程序寿命长除非显式撤销 文件变量文件变量 瞬间变量瞬间变量transient)耐久变量的逆耐久变量的逆每个存储对象都有创建每个存储对象都有创建(生生), 可用可用(
15、活着活着),撤销,撤销(死死)的的生命期。按生命期长短分:生命期。按生命期长短分:静态存储对象静态存储对象 编译时分配存储对象编译时分配存储对象, 近代言语类属对象直到装入后近代言语类属对象直到装入后确立确立(elaboration)之时才定下存储对象叫静态分配之时才定下存储对象叫静态分配 一旦执行不再改动其存储,直至所在存储单元无效一旦执行不再改动其存储,直至所在存储单元无效叫静态叫静态(Static)存储对象存储对象 全局变量均为隐式的静态对象全局变量均为隐式的静态对象, COBOL,BASIC全全静态,静态,ALGOL,C是显示声明静态,是显示声明静态,Pascal除全局,除全局,Ada
16、 不能。不能。 C言语的静态变量是既私有又不随所在声明块中消逝言语的静态变量是既私有又不随所在声明块中消逝, 全局于所在文件。全局于所在文件。auto是静态分配动态装入不叫静态对是静态分配动态装入不叫静态对象。象。Extern是静态对象。是静态对象。externstaticauto动态存储对象动态存储对象 把寿命专长的如文件,全局量排出来归到栈底的某一组,把寿命特短的如循环控制变量另立嵌套组,这个问题也就处理。块5块66块1块2块3块45466546寿寿命命动态存储对象动态存储对象XX 二叉树其大小由输入值定在运转中确立。内存开二叉树其大小由输入值定在运转中确立。内存开辟堆辟堆heap)随生成
17、随堆放动态存储对象。指针即随生成随堆放动态存储对象。指针即堆变量所指程序对象用堆存放堆变量所指程序对象用堆存放 问题:多次重分,内存成了小洞问题:多次重分,内存成了小洞 处理方法:按寿命分组寿命最长的放在较低按处理方法:按寿命分组寿命最长的放在较低按其所在块生命期。其所在块生命期。反复运用反复运用无法再分无法再分堆栈帧管理堆栈帧管理 由动态堆栈联想到普通嵌套式言语可按动态堆栈式管由动态堆栈联想到普通嵌套式言语可按动态堆栈式管理理, 多数变量和所在块寿命一样长多数变量和所在块寿命一样长(言语称之为自动变量言语称之为自动变量) 动态堆栈式存储动态堆栈式存储 按程序动态执行按程序动态执行, , 以动
18、态堆栈管理部分数据和动态以动态堆栈管理部分数据和动态生成数据生成数据 运转时堆栈运转时堆栈Run-time stackRun-time stack其底压入程序代码和全其底压入程序代码和全局,静态量。每执行到调用时生成一个堆栈帧局,静态量。每执行到调用时生成一个堆栈帧(frame)(frame)记录该块数据信息记录该块数据信息, , 每当前往那么部分量自动撤销对于每当前往那么部分量自动撤销对于递归块的部分量可多次生成多次消除。递归块的部分量可多次生成多次消除。 动态链描画调用父辈地址动态链描画调用父辈地址, , 前往地址是继续执行的前往地址是继续执行的下一地址。下一地址。 静态链描画词法父辈静态
19、链描画词法父辈lexical parentlexical parent块地址块地址, , 按该按该块复制部分变量。块复制部分变量。参数参数 前往地址前往地址动态链动态链静态链静态链前往值前往值部分变量部分变量程序代码程序代码全局静态存储全局静态存储首先调用块首先调用块堆栈帧堆栈帧第二调用块第二调用块堆栈帧堆栈帧最新调用块最新调用块堆栈帧堆栈帧暂时变量空间暂时变量空间栈顶栈顶堆栈帧组织堆栈帧组织运转时堆栈运转时堆栈续续调调用用块块首首地地址址本本帧帧词词法法父父辈辈 举例举例 求整数连乘积之递归程序求整数连乘积之递归程序: : function product (jj function prod
20、uct (jj: Integer) Integer): IntegerInteger; var kk var kk: Integer; Integer; begin begin if jj = 0 then product:=1 if jj (4 does (运转时动作指令,运转时动作指令, 取下标取下标) )5 rangecheck (5 rangecheck (函数调用,函数调用, 检查下标检查下标) )6 if (6 if (假设不越界假设不越界) )7 linearsub (7 linearsub (函数调用,函数调用, 计算线性下标值计算线性下标值) )8 then (8 then
21、(给出数组基地址和位移给出数组基地址和位移) )9 9 ; ( (; 切换成解释执行,切换成解释执行, 数据类数据类型定义毕型定义毕) )10 10 11 2by3array box (11 2by3array box (声明并分配名为声明并分配名为boxbox的数的数组变量组变量) )12 10 1 2 box (12 10 1 2 box (给给box(1box(1,2)2)赋值赋值10)10)3.3.3 3.3.3 无类型言语束定无类型言语束定名字名字 束定束定length age 符号表符号表 运转时内存存储对象:类型标签运转时内存存储对象:类型标签scalar numberarray
22、 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 mo
23、d 2 =0) 函数笼统函数笼统 体体顺序声明的顺序声明的Ada例子例子package MANAGER is -package MANAGER is -声明程序包规格阐明声明程序包规格阐明 type PASSWORD is private type PASSWORD is private; - -声明私有类型未定义声明私有类型未定义 NULL_PASSWORD:coustant PASSWORD NULL_PASSWORD:coustant PASSWORD;-立刻用私有类型声明变量立刻用私有类型声明变量 function GET return PASSWORD function GET re
24、turn PASSWORD; - -前往私有类型函数前往私有类型函数 function IS_VALID(P: in PASSWORD) return BOOLEAN function IS_VALID(P: in PASSWORD) return BOOLEAN; PrivatePrivate type PASSWORD is range 0.700 type PASSWORD is range 0.700; - -定义私有类型定义私有类型 NULL_PASSWORD:constant PASSWORD:=0 NULL_PASSWORD:constant PASSWORD:=0 ; - -此
25、时才定义此时才定义end MANAGERend 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 =
26、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; . ca
27、se v2: S2; when vm|vn=Sn; break; when others = St; default: St; end case; next; 执行一个Si跳到end case 没有break要顺序执行,直到next e1e2e3S1S2S3 C C以条件表达式实现选择控制以条件表达式实现选择控制 a=bc ? b:c if (bc) a=b a=bc ? b:c if (bc) a=b; else a=c; else a=c; 条件表达式条件表达式 条件语句条件语句 命令式言语大量依赖顺序命令,命令式言语大量依赖顺序命令, 纯函数式言语完全依赖写纯函数式言语完全依赖写嵌套函数
28、调用。嵌套函数调用。 迭代控制迭代控制迭代普通用于处置同构的、聚集数据构造的反复操作,诸如数组、表、文件。 显式迭代循环,显示迭代有以下几种: 无限循环Bloop name; Bend loop; 有限循环的三种方式:有限循环的三种方式: while_do while_do Exp T FB while Exp loop B: end loop F B Exp TREPEAT BUNTIL Exp;do_until B1 exp1 T F F T exp2B2BEGINB1; WHILE Exp1B2; REPEAT Exp2do_while_doFORTRAN 初始 上界 增量DO L I=
29、EXP1, EXP2, EXP3Adafor BACKDAY in reverse DAY RANGE loop 在循环控制变量和表达式商定上几十年来不断在演化 C采用迭代元素(Iteration element)iterate () = iterate (; ; )对迭代元素不加任何限制。语句,表达式,延续赋值,空均可。先算,再算,假设不为零,那么算然后执行。假设为零出口。假设不为零再算,假设不为零反复以上步骤,假设为零那么出循环。计数循环 例: 用for循环计算表中元素之和 设表list是一简单构造, 一个成分是值value,另一个成分是指向下一表元素的指针next。 可以有以下六种写法:
30、 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 = l
31、ist, 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 = curr
32、ent-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 定
33、义用户定义 : :exception; 系统定义的异常Ada: CONSTRAINT_ERROR 凡取值超出指定范围叫约束异常 NUMBER_ERROR 数值运算结果值实现已不能表达 叫数值异常 STORAGE_ERROR 动态存储分配不够时,叫存储异常 异常定义与处置段 TASKING_ERROR 义务通讯期间发生的异常叫义务异常。 PROGRAM_ERROR 除上四种而外程序中发生的一切异常, 都叫程序异常.如子程序未确立就调用等。 预定义的可以显式也可以隐式引发,而用户定义的异常必需 显式引发 引发语句: raise ; 引发语句可出如今任何可执行语句所在的地方。一旦引发,那么本程序块挂
34、起转而执行本块异常处置段中同名的异常处置程序。每个程序块都可以在该块末尾设立异常处置段: declare: ; ; begin: ; ;exception: when = -异常处置段 when。 -普通再次引发原异常缺省名字 end;Java的异常处置语句,try_catch_finally: try /能够有异常语句组 /用throw 显式抛出异常 /也可以隐式自动抛出异常 catch( ) /异常处置段-1 /catch捕捉try 中抛出的异常对象 /不匹配那么跳过本catch 不执行 catch ( ) /异常对象段-2 /匹配执行后跳过一切catch finally /善后处置段 /
35、只需进入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,
36、 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 DIA
37、METER PUT (Diameter too large ! please reenter.); 5end ;6end loop; PUT (“processing finished.); PUT New_line; end CIRCLE;3.5 3.5 函数和过程函数和过程 命令式言语中子程序有两种方式:函数(必需前往值)也叫函数,过程(实施一组动作)也叫子例程subroutine。它们是程序的第一次分割,这种分割的益处: 实施的功能单一,便于调试; 相对独立,便于多人分工完成,且时间不受约束; 相对封锁,人们易于控制,是分解复杂性的有力措施。 子程序和主程序联络的接口特别重要。在这个界面
38、上要指出该例程的数据特征, 即输入什么输出什么。而整个子程序体是完成从输入到输出的实现手段。 界面指出“做什么?,而子程序体回答“怎样做。 80年代程序完成第二次分割: 将子程序定义(即界面)和子程序体显式的分开, 成为相对独立的规格阐明(Specification)和体(body)。3.5.1 3.5.1 函数和过程笼统函数和过程笼统 函数笼统是用一个简单的名字笼统代表一个函数。函数由函数型构(Signature)和函数体(body)组成。函数计算的目的是求值。函数体等同于一个复合的表达式。函数笼统是对表达式的笼统 过程笼统是用一个简单的名字笼统代表一个计算过程。过程由过程型构和过程体组成。
39、过程调用的目的是执行一组命令过程笼统是对命令(即语句)集的笼统 函数由函数型构和函数体组成。方式是: function FUNC (fp1,fp2,.):returntype;/函数型构 B; /函数体,可包括任何声明和语句 其中fp1,fp2,为方式参数,也叫方式变元(argument)returntype 为函数前往值的类型 函数援用是运用函数的独一手段,它在同名的函数名之下给出实 在参数(真实变元): FUNC (ap1,ap2,.); 各种言语函数定义(a) FORTRAN INTEGER FUNCTION FACT(N) /前缀指明前往类型 INTEGER N,I,F /参数类型在此
40、声明 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; /ANS
41、I 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) /入口在子程序顶部假设THE
42、TA是弧度值时,那么: CALL RADR,THERA,X,Y /入口在子程序中FORTRAN的指定前往SUBROUTINE RMX,Y,*,*,* . . .RETURN2 /前往语句标号80 . . .RETURN1 /前往语句标号70 . . .RETURN3 /前往语句标号120 . . .END CALL RM(A,B,70,80,120) 形实参数表中元素个数,次序,类型应一致。早期言语都严厉遵此准那么。近代言语提供了较多的灵敏表示法。 Ada引入缺省参数,实参个数可少于形参个数;指明参数结合不思索次序;Ada引入参数方式in,out,inout指明只读,只写,读写参数。 C言语允
43、许恣意多个参数的调用。如内定义函数printf()调用时可以写恣意个输出,只是第一参数中的格式个数与参数个数对应。 过程定义与调用 过程子程序定义方式 procedure PROC (fp1,fp2,.) /过程型构 B; /子程序体包含局声明 对应的过程调用是: PROC (ap1, ap2, .); C言语一切过程,包括主程序都是函数过程。它以void(无值)关键字替代函数类型指明符,实施子程序过程语义 援用或调用的方式 无参过程- 函数和过程的参数表均可为空。有的言语保管(),有的只需一个名字。普通无参过程也要更新过程内部的值。函数过程还会前往不同的值。全局量在函数中有效。改动了全局量两
44、次调用结果值当然不一样。这就是函数的副作用(side effect)。 - 有副作用的函数 C 在很大程度上利用函数副作用,例如,当需求跳过空白时写: while (c = getch() = ); - Ada中常用的随机数: function RANDOM return FLOAT range 0.01.0;援用时, 假设FIELD已声明为常量: RESULT = RANDOM * FIELD;RANDOM假设无副作用RESULT值不能够改动。3.5.2 参数机制言语中第一类对象均可作函数/过程参数。 由于变量的时空特性,传送的形-实参数可以有许多不同的实现结合的方法,即参数机制。传值调用c
45、all-by-value1实参表达式先求值2将值复制给对应的形参。形参和实参有同样大小的存储3过程运转后普通不再将改动了的形参值复制回实参 Pascal中的传值调用 PROCEDURE test1(J2,A2:Integer;P2:list) BEGINWriteln(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 $堆 栈 帧中 的 调用 程 序 J1 A1 P1 1264530*$/% 堆
46、栈 帧 中 的 过 程 t est1 2 J2 A2 P2 130指针 束定传值调用图示 传名调用(call-by-name)传名在过程/函数中加工的就是实参已分配的值,因此不需付出双倍存储代价。但传名过程的真假结合是将程序体中一切形参出现的地方均以实参变元名置换。这样出现几次算几次效率是低的。传名调用程序例如由于Pascal无传名机制,此处作一点扩展:PROCEDURE test2(NAME J2,A2:Integer;NAME P2:List); 函数体同test1执行同样调用:test2(J1,A1J1,P1.next);名结合后打印: 1 30 %执行后结果是: 2 45 $*$/%
47、堆 杖 帧中 过 程 t e st2 就是 J2 就是 A2 就是 P2 J1P1。 n extA1J1 传名调用图示堆 栈 帧中 的 调用 程 序 J1 2 A1 P1 1264530援用调用援用调用(call_by_reference)(call_by_reference)援用参数实现时, 编译器在子程序堆栈中设许多中间指针, 将形参名束定于此指针,而该指针的值是实参变量的地址(在主程序堆栈框架内),在子程序中每次对形参变量的存取都是自动地递援用到实参存储对象上。援用调用的Pascal例如: PROCEDURE test3(VAR J2,A2:Integer;VAR P2:List); 函
48、数体同test1相应的调用程序是:test3(J1,A1J1,P1.next); 第一次打印是: 1 30 %第二次打印是: 2 30 $援用调用图示堆 栈 帧中 的 调用 程 序 2 J1 A1 P1 11264530*$/% 堆 栈 帧 中 的 过 程 t est1 J2 A2 P2 参数方式与前往调用(call-by-return)显式指明参数传送方式,可以为编译实现提供信息 fun_name(x,y:Real; VAR s,q:Integer).x,y传值实现,它只读。s,q援用实现,可读/写Ada只规定参数方式in,out,inout,传送方向的方式(mode)。由编译选择实现方式:
49、 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定 正常顺序执行对于并发多义务宜只读只写 值与前往调用
50、机制是把值调用和前往调用组合起来,实现调用程序双向通道,这对于有多个存储器的多处置器系统和网络分布式系统值调用极度平安在子程序执行期间因不是束定, 形参变量的值不会中途改动, 复制回去和拷贝进来处可设断点检查P1P2P1P2P1P2 指针参数call_by_point指针作为参数其实现方式普通是复制机制,它复制的是地址(指针内容)留意和援用调用之同异例:指针Pascal援用版: 交换两变量的内容PROCEDURE swap1( VAR a,b:Integer); VAR t:Integer;BEGIN T = a; a = b; b = tEND;调用程序片断: j = 3; k = 5; s
51、wap1(j,k); /结果j = 5, k = 3J =3K=5Caller-frame= a= t= b3= 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);主 调程 序 堆 栈 帧 jp kp 堆 栈 帧 中 的 S WAP2 a b t 3 指
52、针调用图示 动 态 堆 35C言语的指针参数传送 void swap3(int *a, int*b) int t; t = *a; *a = *b; *b = t; 形参是两指针, 实参不用指针的版本: main() int j = 3; k = 5; /声明并初始化两整数 swap3(&j,&k); /类型匹配吗? 主 调 程 序 堆 栈 框 架 j k 5堆 栈 框 架 中 的 SW AP3 a b 3 t C语言的指针- - 引用调用3.6 3.6 笼统与封装笼统与封装 函数和过程是封装的程序实体,它有数据和操作,规格阐明型构和过程体,一体使于人们控制复杂性 Pascal
53、一致的嵌套构造不造于大型程序main代 码Sub2数 据 代 码Sub1数 据 代 码main数据main数据mainSub110Sub1115Sub1621Sub22284321小程序结构小程序结构大程序结构大程序结构数据2sub1-sub10数据4sub22-sub28数据1sub11-sub15数据3sub16-sub21main续 将相关的数据和操作封装成大模块假设干类型,假设干过程/函数 构造上构成包package或模块 Modula包是可分别编译。随时衔接软件资源,是处理复杂系统的有力手段包的规格阐明和包体显式分开。语义上正好是“作什麽,“怎麽做数据对象和类型子程序规格(操作)(操
54、作)私有数据子程序体子程序体子程序体私有操作程序包体规格说明外界可见3.6.1 模块和包 规格阐明和体在表示构造上的分别。有利于修正,维护 封装实现数据隐藏,有利于平安 规格阐明是程序包的笼统,有利于复杂系统简化 模块包封装数据与操作,它有可控界面,外界不模块包封装数据与操作,它有可控界面,外界不能支配私有数据引出公有能支配私有数据引出公有publicpublic包的运用者可见、私包的运用者可见、私有有privateprivate本包一切操作可访问,包外不可见、维护本包一切操作可访问,包外不可见、维护protected,protected,包外不可见,但本包的子包可见概念包外不可见,但本包的子
55、包可见概念 包只是以封装手段包只是以封装手段, ,可有可有/ /可没有逻辑语义可没有逻辑语义-只需数据无操作,数据块只需数据无操作,数据块BLOCK DATABLOCK DATAFORTRANFORTRAN-只需操作无共享数据如函数包,数学库只需操作无共享数据如函数包,数学库-有数据有操作,一口对外可模拟自动机有数据有操作,一口对外可模拟自动机-有数据有操作,模拟客观世界对象有数据有操作,模拟客观世界对象添加程序表达才添加程序表达才干干-封装的包可实现复杂的数据类型封装的包可实现复杂的数据类型ADTADT Ada 的复数程序包 package COMPLEX is type NUMBER is
56、 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_
57、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 3.6.2 笼统数据类型笼统数据类型 数据笼统数据笼统数据笼统是笼统数据类型的方法学数据笼统是笼统数据类型的方法学定义一组数据集定义一组数据集V V,以及其上的操作集,以及其上的操作集OpOp,构成,构成AD
58、TADTAbstract Data TypeAbstract Data Type T=( V , Op ) T=( V , Op )-什么和怎样做分开什么和怎样做分开( (规格阐明和体规格阐明和体) )-实现数据隐藏体中声明的数据和操作外界不可见实现数据隐藏体中声明的数据和操作外界不可见-分别开发分别编译可做大程序分别开发分别编译可做大程序-简化复杂性便于调试利用笼统实现分治简化复杂性便于调试利用笼统实现分治-构造新类型,计算直观方便面向对象的根底构造新类型,计算直观方便面向对象的根底构造新类型构造新类型Swith COMPLEY use COMPLEY;Procedure MAIN is C
59、1: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-*+NumberLEXCOMP 构造函数和析构函数变量类型 V : integer;以类型指明程序对象变量笼统数据类型, 声明时要指明如何构造C:NUMBER:=1.0,2.0) 较简单可用赋初值方法,复杂在运转中由构造函数constructor)完成 C = ADT_Name( 构造函数constructor) 和ADT同名不再运用的程序对象,用析构函数destructor
60、)显式删除普通方式是:ADT_Name() 和ADT同名 ADT_Name( ) C C言语以文件实现笼统数据类型言语以文件实现笼统数据类型 C C言语言语4 4种文件种文件 - -头文件头文件“modules.h“modules.h 定义宏和类型声明定义宏和类型声明 - -主模块主模块“name.c“name.c 给出新类型的数据和操作定义给出新类型的数据和操作定义 - -其它模块其它模块“other.c“other.c 实现头文件中声明实现头文件中声明 - -经过经过makefilemakefile指明各文件关系指明各文件关系 make SOMETYPE make SOMETYPE SOMETYPE SOMETYPE:
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 基础教育阶段跟岗实习教师协议范本
- 三年级数学计算题专项练习汇编及答案集锦
- 新能源商用车辆在化工行业的市场需求与应用前景报告
- 康复医疗器械市场2025年需求结构与产品创新趋势研究报告
- 2025年度电子商务合同反不正当竞争法律保护合同
- 2025版可下载健身课程包月合同
- 二零二五年度物流仓储服务内部承包管理协议
- 二零二五年度房地产合作开发项目预交保证金及质量监督协议
- 2025版敬老院公共设施改造与升级建设合同示范
- 2025版绿色环保型办公场所带物业全包租赁协议
- 广东省省实、二中、执信、广雅、六中2024-2025学年高一下期末联考语文试题及答案
- 生物医药研发股东风险共担协议书
- 2025年武汉市汉阳区社区干事岗位招聘考试笔试试题(含答案)
- 党课课件含讲稿:《关于加强党的作风建设论述摘编》辅导报告
- 2025高考物理答题技巧构建模板:机械能守恒定律(五大题型)(试卷+答案解析)
- friends老友记中英文对照-全十季剧本
- ISO 141552020医疗器械的人体受试者临床试验-临床试验质量管理规范简介
- DB37-T 3577-2019水泥稳定碎石基层施工技术规范
- 氢气压缩机操作规程
- 屋顶分布式太阳能光伏发电站项目全套图纸
- 常见的肛肠疾病精编ppt
评论
0/150
提交评论