广东省汕头市金山中学高中信息技术 竞赛班第二阶段培训 第七课 过程与函数教案.doc_第1页
广东省汕头市金山中学高中信息技术 竞赛班第二阶段培训 第七课 过程与函数教案.doc_第2页
广东省汕头市金山中学高中信息技术 竞赛班第二阶段培训 第七课 过程与函数教案.doc_第3页
广东省汕头市金山中学高中信息技术 竞赛班第二阶段培训 第七课 过程与函数教案.doc_第4页
广东省汕头市金山中学高中信息技术 竞赛班第二阶段培训 第七课 过程与函数教案.doc_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

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

文档简介

7 过程、函数pascal语言实现结构化程序设计的主要手段之一是使用子程序过程及函数,利用过程和函数,把程序中需要多次重复使用,且具有特定功能的程序段,单独编写成一个称为子程序的程序段,它存贮一次,但可以在程序的多个地方被调用,处理不同的数据。7.1 过 程 (子程序)过程说明的一般形式:procedure ();(说明部分);begin;end;其中procedure 是保留字,它说明这一段程序是过程,一个过程对应一个procedure。过程名是自定的标识符,程序通过过程名调用这段程序。参数表是用于向过程传递数据的变量的说明。说明部分则是过程内部所使用的变量的说明。请分析下面程序的具体执行过程。program ex1;var u,v:integer;procedure p1(x,y:integer); 过程说明var i,j:integer;beginfor i:=1 to x dobeginj:=y+i;write(j);end;end;begin 主程序u:=6; v:=5;p1(u,v); 过程调用writeln;u:=u+v; v:=u*v;p1(u,v); 过程调用write(end);end.分析如下: 程序从主程序的执行部分开始 u6 v5 (过程调用) 参数传递: x u=6 y v=5 p1(u,v) 执行过程体,输出: 6 7 8 9 10 11 返回主程序调用处(调用结束) writeln; u6+511 v11*5=55 (过程调用) 参数传递: x u=11 y v=55 p1(u,v) 执行过程体,输出: 56 57 58 59 60 61 62 63 64 65 66 返回主程序调用处(调用结束) 输出: end以上例子仅说明过程在程序中如何说明和调用,有关参数的传递问题在下面细述:1 无参过程过程中最简单的是无参过程,这种过程的首部只有过程名,而没有参数表部分。【例1】利用过程画一条横线。program draws; procedure line; 无参过程const length=10;var i : integer; beginfor i:=1 to length do write();writeln; end;begin line; writeln ( hello ! ); line;end. 输出: hello! 无参过程只能执行一种固定的功能,如调用line过程时,只能固定地画出10个的横线,如果要在调用时能灵活地画出不同长度的横线,就必须运用有参过程。2有参过程有参过程可以在每次调用时,根据不同的参数处理不同的数据,更大程度地发挥过程的优越性。【例2】利用过程,按需要画出不同长度的横线。program drawline;var i,x,n:integer;procedure line(length:integer); 有参过程,length为形式参数var i:integer;beginfor i:=1 to length do write();writeln;end;beginreadln(n); n为需要画的横线条数for i:=1 to n do begin readln(x); x为每条横线的长度 if x100 then line(100) else line(x); x为实际参数end;end.运行结果:3 5 -4 8 上例过程是含有参数的过程,在过程说明时,过程名后参数表中的参数称为形式参数,而在调用过程时,过程名后括号中的参数称为实际参数。每次调用过程时,通过实际参数对形式参数进行赋值。实际参数对应于过程说明中的形式参数,实参和形参的个数、类型要一一对应。3值参数和变量参数有三种类型的参数:值参、变参和无类型参数。当前面没有保留字var,后跟类型的参数称为值参数;如: procedure logon(x,y:real);当前面有保留字var,后跟类型的参数称为变量参数;如: procedure ex(var ch:char);当前面有保留字var,但后不跟类型的参数称为无类型参数;如:procedure sw(var a1,a2);这里主要叙述值参数和变量参数。请比较以下程序及运行结果:program zc; var n:integer; procedure a(x:integer); var i:integer; beginfor i:=1 to x do write();writeln;x:=x+10; end;begin read(n); a(n); writeln(n=,n);end.program bc; var n:integer; procedure b(var x:integer); var i:integer; beginfor i:=1 to x do write();writeln;x:=x+10; end;begin read(n); b(n); writeln(n=,n);end.运行结果:5 n=5运行结果:5 n=15值参数接受相应实际参数所传入的值,在过程a中,值参x的改变不会影响给它传递数值的实参n。调用过程时,值参数的形式单元直接接受相对应的实际参数的值,可称为输入参数,如图7.1_1所示。过程执行完,值参的值也不再保留,值参是这一过程的局部变量,仅在此过程内有意义,不能用它去传递过程的结果。实际参数 n x 值参数 n x 55 5 图7.1_1而变量参数在过程中的改变会直接影响给它传递数值的实际参数,即实数随时随着变参的变化而变化。因为实际参数给变参传递的是实参自身的地址,而不是数值,如图7.1_2所示,那么对变参的操作其实就是对变参的操作。实际参数 n x 值参数5 图7.1_24全程变量和局部变量在主程序的说明部分定义的变量,称为全程变量,它适用于整个程序,主程序以及它所包含的子程序都能对它进行存取访问。在子程序的说明部分定义的变量,称为局部变量,它仅适用于相应的子程序,只允许在定义它的子程序范围内对它进行存取访问。有些变量可能既在主程序中定义,又在子程序中定义,这种变量称为同名的全程变量和局部变量。程序运行时,在定义它的子程序中局部的那个变量起作用,在主程序及其它子程序中全程的那个变量起作用。因为它们占用不同的存贮单元,所以不会造成混乱。【例3】下面的程序有两个过程,一个是求连续数的和,一个是求连续数的积。请通过这个程序,比较全程变量和局部变量。program dd;var x,n:integer; x,n为全程变量procedure sum; 连续求和var i:integer; i为局部变量beginx:=0;for i:=1 to n do x:=x+i;end;procedure pro; 连续求积var j:integer j是局部变量begin n:=1; for j:=1 to x do n:=n*j;end;begin 主程序 readln(n); sum; writeln(x1=,x); pro; writeln(n1=,n); sum; writeln(x2=,x);end.运行结果:输入: 2输出: x1 = 3 n1 = 6 x2 = 21【例4】下面的程序说明全程变量与局部变量同名的情况。program same;var x:integer; 全程变量procedure let; var x:integer; 局部变量beginx:=1;writeln(x);end;beginx:=0;let;writeln(x);end.运行结果:输出: 1 局部量 0 全程量从上例可看出,调用过程let时,只有局部变量起作用,而同名的全程量在过程中无效;在主程序中,只有全程量起作用,局部量已不存在。所以使用变量时一定要注意它的作用域。【例5】 求1000以内的亲密数对a和b,且输出ab的数对。当正整数a的因子和是b,b的因子和又是a,则称a和b是一对亲密数。如:12的因子1、2、3、4、6,其和是16;而16的因子1、2、4、8,其和是15,则12和15不是亲密数对。而6的因子和是1+2+3=6,即6的因子和是a本身,这说明6和6是亲密数对。解: 本题的关键是解决计算因子和的问题,若求出a的因子和是b,再求出b的因子和是c,那么当ac时,a和b时亲密数对,若ac,则输出a和b。 用枚举法,从2到1000逐一检查。program pair;var a,b,c:integer;procedure fsum(x:integer; var y:integer); 计算因子和的过程var i:integer;beginy:=1;for i:=2 to (x div 2) doif x mod i =0 then y:=y+i;end;beginfor a:=2 to 1000 do beginfsum(a,b); 计算a的因子和afsum(b,c); 计算b的因子和cif (a=c)and(ab) then writeln(a:6,b:6); 若是不相等的亲密数则输出数对end; forend.运行结果:输出: 220 284 284 2207.2 函 数函数和过程一样,是程序中的一个独立部分,可在程序的其他地方调用。函数说明的一般形式:function ():;begin;end;函数与过程有所不同,在于函数具有返回值,函数类型即其返回值的类型。先回顾一下pascal语言所提供的标准函数,如:函 数 函数功能函数值例abs(x): real绝对值abs(13.2)= 13.2sqr(x): real平方sqr(1.2)= 1.44sqrt(x): real平方根sqrt(100)= 10.0odd(x): boolean奇函数当x为奇数时值为true,为偶数时值为false根据函数的不同返回类型,可在程序的表达式中直接调用函数,如:program xx;var y, t : real; w : integer;begin read(u); if odd (u)=true then y:=abs(3.5) else y:=abs(-5.2);t:=sqr(y)+sqrt(y); end.类似地,我们可以在主程序的表达式中直接使用已定义的自定义函数。下面我们看看如何自定义一个函数。【例6】定义一个函数,从输入的三个数中返回其中最大的一个,若最大值为负数,则返回0。function findmax (a, b, c : real) : real; var temp:real;begin if ab then temp:=a else temp:=b; if ctemp then temp:=c; if temp0 then findmax:=0 给函数赋值else findmax:=temp; 给函数赋值end;在函数中,必须有给函数赋值的语句,即函数将返回的值。【例7】求五边形面积,边长l1l7由键盘输入。s1l2s2s3l1l6l3l7l5l4 (求五边形面积可以变成求3个三角形的面积的和。) 算法: 1输入边长l1l72根据l1、l2、l6计算三角形面积s13根据l6、l3、l7计算三角形面积s24根据l7、l4、l5计算三角形面积s35将s1、s2、s3相加得到五边形的面积s6输出五边形的面积s这个算法中要3次计算三角形的面积,可将计算三角形的面积定义成函数,然后在主程序中3次调用。设已知三边求三角形面积的函数为ts,它有三个形式参数a、b、c (对应三角形的3条边)。修改后的算法为:1 输入l1l72 计算 s := ts(l1, l2, l6) + ts(l6, l3, l7) + ts(l7, l4, l5)3 输出s程序清单:program area;var l1,l2,l3,l4,l5,l6,l7,s:real;function ts(a,b,c:real):real; 计算三角形面积tsvar p:real;begin p:=(a+b+c)/2; ts:=sqrt(p*(p-a)*(p-b)*(p-c); 海伦公式end;beginread(l1,l2,l3,l4,l5,l6,l7); 输入各边长s:=ts(l1,l2,l6)+ts(l6,l3,l7)+ts(l7,l4,l5); 计算五边形面积writeln(area=,s); 输出面积end.函数和过程一样都是子程序,所以前面关于过程的参数、作用域等问题的同样适用于函数。函数和过程的主要区别是前者返回一个值,可用于表达式操作数,后者则用来完成一个或多个任务。7.3 过程参数和函数参数过程和函数都可以嵌套使用,即一个子程序可以调用其它子程序。如果在一个程序中要求某一过程或函数根据不同情况调用几个不同的子程序,较好的方法是允许子程序作为过程或函数的参数。turbo pascal 5.0 以上版本允许使用过程参数和函数参数,它的一般形式如下:过程参数: procedure 形式过程名(形式过程的形式参数);函数参数: function 形式过程名(形式过程的形式参数);【例8】定义函数计算和式 function sigma(function f(i:integer):integer; n1,n2:integer):integer;var j,sum:integer;beginsum:=0;for j:=n1 to n2 do sum:=sum+f(j);sigma:=sum;end;就是函数参数的形式说明,具体调用sigma时,要用和f类型、参数量相匹配的实际函数来替代,但不能用标准过程或标准函数作为过程参数和函数参数的实参。7.4 提前调用pascal语言要求过程调用和函数调用时,被调用的过程或函数必须提前说明。即过程a调用过程b,过程b必须先于过程a进行说明。函数亦然。program xx; begin 过程b(); 过程a(); end. 调用过程b如果过程a和过程b互相调用,或过程a必须位于过程b之前时,必须使用“提前调用”解决此矛盾。把子程序(过程或函数)的首部与其分程序分开说明,这称为子程序的提前调用。分离的子程序首部和正常的子程序首部完全一样,只是在其后面加上保留字 forward ;而其分程序则在稍后的位置上加以说明,以子程序首部的副本开头,该副本只留下该子程序的名字,不带参数表和返回类型。【例9】 program catch;var x:integer;function up(var i:integere):integer:forward;function down(var i:integer):integer;begini:=i div 2; writeln(i);if i1 then i:=up(i); 提前调用end;function up: 副本beginwhile i mod 20 do begin i:=i*3+i; writeln(i);end;i:=down(i);end;begin 主程序write(enter any integer:);readln(x);x:=up(x);write(ok!);end.输入: 6输出: 31051684 21ok!7.5 递归调用一个函数、过程或其它数据结构,如果在定义或说明的内部又直接或间接地出现定义本身的引用,则称为递归。递归调用即过程或函数自身调用自身。递归形式一般有两种直接递归和间接递归,而栈是实现递归的重要手段。(一)、直接递归子程序自己调用自己1 n=1nfac (n-1) n1【例2】 fac (n) = n! = 按上述递归定义形式写出fac(n) 函数如下:function fac(n:integer):integer;beginif n=1 then fac:=1else fac:=n*fac(n-1);end;它的执行流程如下:fac (4)fac (4)fac (3)fac (2)fac (1)4fac (3)3fac (2)2fac (1)fac (1) = 124一般来说,递归子程序在调用本身前应有条件语句控制何时进行递归,何时递归结束。这个条件语句就是递归边界。例如,fac函数体中的“ if n=1 then fac:=1 ”。 递归调用的常用到模式:procedure digui (参数表); 局部说明;begin if 边界条件 then 边界值赋值并返回 else begin 处理语句 digui(); 递归调用 处理语句 end;end; 递归调用的参数与堆栈: 值参数 在进行递归调用时,先将本层的值参保存在系统的堆栈空间中,再进入下一层;从下一层返回时,先从堆栈中恢复本层值参的值,再往下执行。即返回后的值应是恢复后的值,也就是在进行递归调用前的值。 值参数仅仅将数据传给下一层,下一层的值参并不返回影响上层的值参。 变量参数变量参数不仅将数据传给下一层,而且会将下一层的变参的值带回到上层。由于递归调用须在内存中开辟堆栈区,专用于保存递归调用前的数据及地址。pascal对堆栈区大小的默认设置为16k(16*1024byte)。若堆栈区太小,往往会发生堆栈溢出的情况,所以有时需调整堆栈区的大小。设置方法如下:a. 选择菜单栏 option-compiler-memory sizes stack size : 堆栈段大小,最大可设置为65520; low heap limit : 可接受到最小堆空间,默认为0,一般不需改动此项; high heap limit: 指定最大堆空间,必须大于等于最小堆空间,默认为655360;b. 通过编译命令,位于程序第一行,即program之前 $m 堆栈区大小,堆的最小值,堆的最大值 如: $m 65520,0,655360 (二)、间接递归子程序a调用子程序b,子程序b又调用子程序a子程序a和b组合起来有两种结构形式:1b是a的局部对象例: procedure a;procedure b;begina的子过程b的过程说明 a; 在b中调用a endbegin b; 在a中调用b end;2a和b是两个地位相同的子程序例: procedure b (形式参数表): forward; b的完整说明在后procedurde a;begin b (实参表); 在a中调用bend;procedure b; b的首部缩写,形式参数表不再列出begina; 在b中调用aend;练 习 七1 求给定的五个数中的最大值(用过程/函数编制求三个数的最大值,二次调用此过程/函数)。2 哥德巴赫猜想之一是任何大于5的奇数都可以表示为3个素数之和,请用10个大于5的奇数验证这一论断。奇数用随机函数产生,把验证编写为过程,打印出每个数和组成该数的三个素数。3 编程计算组合数 ,将其中求 i! 编写成函数。 4 指出下列程序中的全程变量、局部变量、变量参数、数值参数,写出程序运行后的输出结果。program

温馨提示

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

评论

0/150

提交评论