您好,欢迎访问三七文档
第六章函数与过程第一节函数第二节过程第三节递推算法第四节递归前面我们曾经学习了程序设计中的三种基本控制结构(顺序、分支、循环)。用它们可以组成任何程序。但在应用中,还经常用到子程序结构。通常,在程序设计中,我们会发现一些程序段在程序的不同地方反复出现,此时可以将这些程序段作为相对独立的整体,用一个标识符给它起一个名字,凡是程序中出现该程序段的地方,只要简单地写上其标识符即可。这样的程序段,我们称之为子程序。子程序的使用不仅缩短了程序,节省了内存空间及减少了程序的编译时间,而且有利于结构化程序设计。因为一个复杂的问题总可将其分解成若干个子问题来解决,如果子问题依然很复杂,还可以将它继续分解,直到每个子问题都是一个具有独立任务的模块。这样编制的程序结构清晰,逻辑关系明确,无论是编写、阅读、调试还是修改,都会带来极大的好处。在一个程序中可以只有主程序而没有子程序(本章以前都是如此),但不能没有主程序,也就是说不能单独执行子程序。Pascal中子程序有两种形式:函数和过程。第一节函数在此之前,我们曾经介绍并使用了Pascal提供的各种标准函数,如Abs(),Sqr()等等,这些系统提供的函数为我们编写程序提供了很大的方便。比如:求sin(1)+sin(2)+...+sin(100)的值。但这些函数只是常用的基本函数,编程时经常需要自定义一些函数。我们来看看下面一个例子:求:1!+2!+3!+...+10!=?如果要编写程序,我们看到求阶乘的操作要执行10次,只不过每次所求的数不同。我们想:不至于编写10遍求阶乘的程序吧。我们希望有一个求阶乘的函数,假设为js(x),那么我们就可以这样求这道题了。例6.1Programex6_1;vari:integer;sum:longint;BEGINsum:=0;fori:=1to10dosum:=sum+js(i);writeln('sum=',sum);END.现在的问题是:FreePASCAL没提供js(x)这样一个标准函数,这个程序是通不过的。如果是PASCAL的标准函数,我们可以直接调用,如trunc(x),ln(x),sqrt(x)......而PASCAL提供给我们的可供直接调用的标准函数不多。没关系,我们编写自己的函数!函数的定义在Pascal中,函数也遵循先说明后使用的规则,在程序中,函数的说明放在调用该函数的程序(主程序或其它子程序)的说明部分。函数的结构与主程序的结构很相似。函数定义的一般格式:Function函数名(形式参数表):函数类型;//函数首部说明部分;begin//以下是函数体语句1;……语句n;end;说明:①函数由首部与函数体两部分组成。②函数首部以关键字Function开头,表示子程序是一个函数。③函数名是用户自定义的标识符。④函数的类型也就是函数返回值的类型,所求得的函数值通过函数名传回调用它的程序。可见,函数的作用一般是为了求得一个值。⑤形式参数简称形参,形参即函数的自变量。自变量的初值来源于函数调用。在函数中,形参一般格式如下:变量名表1:类型标识符1;变量名表2:类型标识符2;…;变量名表n:类型标识符n。可见形参表相当于变量说明,对函数自变量进行说明。⑥当缺省形参表(当然要同时省去一对括号)时,称为无参函数。⑦函数体与程序体基本相似,由说明部分和执行部分组成。⑧函数体中的说明部分用来对本函数使用的标号、常量、类型、变量、子程序加以说明,这些量只在本函数内有效,有效范围是局部的。。⑨函数体的执行部分由begin开头,end结束,中间有若干用分号隔开的语句,只是end后应跟分号,不能像程序那样用句号.。⑩在函数体的执行部分,至少应该给函数名赋一次值,以使在函数执行结束后把函数值带回调用程序,新版本支持用exit(返回值)命令带出返回值。编写一个阶乘的函数,我们给此函数取一个名字js。Functionjs(n:integer):longint;Vari:integer;s:longint;begins:=1;fori:=1tondos:=s*i;js:=s;end;在本例中,函数名叫js,只有一个integer型的自变量n,函数js属longint型。在本函数中,要用到两个变量i,s,在var后已加以说明。在函数体中,是一个求阶乘的语句,但有一点要注意:虽然n的阶乘的值在s中,但最后必须将此值赋给函数js,此时js不带任何参数。在任何函数中,最后都要把最终结果赋给函数名,因为该函数的结果是靠函数名返回的。在这里,函数的参数n是一个接口参数,说得更明确点是入口参数。如果我们调用函数:js(3),那么在程序里所有有n的地方,n被替代成3来计算。在这里,3就被称为实参。又如:sqrt(4),ln(5),这里4,5叫实参。而ln(x),sqrt(x)中的x,y叫形参。函数的调用我们可以在任何与函数值类型兼容的表达式中调用函数,或者说,函数调用只能出现在允许表达式出现的地方,或作为表达式的一个因子。函数调用方式与标准函数的调用方式相同。函数调用的一般格式:<函数名>或<函数名>(实在参数表)说明:①实在参数简称实参。实参的个数必须与函数说明中形参的个数一致,实参的类型与形参的类型应当一一对应。②调用函数时,一般的,实参必须有确定的值。③函数调用的步骤为:计算实参的值,赋给对应的形参;我们对函数进行了定义,在后面的程序中都可以象标准函数那样直接调用自定义函数了。我们对例6.1用自定义函数进行编写程序。例6.2求1!+2!+……+10!的值。程序如下:Programex6_2;vari:integer;sum:longint;Functionjs(n:integer):longint;vari:integer;s:longint;begins:=1;fori:=1tondos:=s*i;js:=s;end;BEGINsum:=0;fori:=1to10dosum:=sum+js(i);writeln('sum=',sum);END.函数的应用举例例6.4利用前面定义的阶乘函数,求5!,9!。程序如下:Programex6_4;Vara1,a2:longint;Functionjs(n:integer):longint;Vari:integer;s:longint;begins:=1;fori:=1tondos:=s*i;js:=s;end;BEGINa1:=js(5);a2:=js(9);writeln('5!=',a1,'','9!=',a2);END.在这个程序中,在主程序的BEGIN之前,我们对函数进行了一次说明,在后面的程序中都可以象标准函数那样直接调用自定义函数了。在Function语句中,用的是形参n,在主程序调用中,调用函数是用的实参,如:js(5);程序执行到这儿会自动将5代入前面的Function函数中,用5取代所有的n,最终将结果赋值给js。所以在a1中一定是5!,a2中是9!。另外,函数不能单独使用,一定要结合主程序才能运行。主程序的变量a1,a2叫全程变量,它们除了主程序外,还可以在函数中出现;在函数说明中用到的变量i,s则是局部变量,只能在函数部分使用,一旦出了函数则失去意义;别外要注意:全程变量和局部变量尽量不要同名。例6.5任意输入10组三角形的三边,求其面积。我们可以定义一个已知三角形三边求其面积的函数,设为area(a1,a2,a3)。程序如下:Programex6_5;Vara,b,c,s:real;i:integer;Functionarea(a1,a2,a3:real):real;vars1,d:real;begind:=(a1+a2+a3)/2;s1:=Sqrt(d*(d-a1)*(d-a2)*(d-a3));area:=s1;end;BEGINfori:=1to10dobeginwriteln('inputa,b,c');readln(a,b,c);if(a+b=c)or(a+c=b)or(b+c=a)thenwriteln('dataerror!')elsewriteln('s=',area(a,b,c));end;END.在函数说明中,如果形参的个数不止一个,那么在程序中调用函数的实参个数一定要与形参的个数一致,第一个实参对应第一个形参,第二个实参对应第二个形参...次序不能对调。例6.6定义一个函数CHECK(N,D),让它返回一个布尔值。如果数字D在整数N的某位中出现则送回TRUE,否则送回FALSE。例如:CHECK(325719,3)=TRUE;CHECK(77829,1)=FALSE;Programex6_6;VARa,b:integer;Functionheck(n,d:integer):boolean;varf:boolean;e:integer;beginf:=false;while(n0)and(notf)dobegine:=nmod10;n:=ndiv10;ife=dthenf:=true;end;check:=f;end;BEGINwriteln('inputn,d');read(a,b);writeln(check(a,b));END.例6.7计算如图多边形的面积。从图中可以看出,五边形的面积是三个三角形面积之和。b1b2b3b4b5b6b7程序如下:Programex6_7;Varb1,b2,b3,b4,b5,b6,b7,s:real;Functionarea(a,b,c:real):real;VarP:real;BeginP:=(a+b+c)/2;Area:=sqrt(p*(p-a)*(p-b)*(p-c));End;BEGIN{主程序}Write(‘pleaseinputb1,b2,b3,b4,b5,b6,b7:’);Readln(b1,b2,b3,b4,b5,b6,b7);S:=area(b1,b5,b6)+area(b2,b6,b7)+area(b3,b4,b7);{三次调用函数area}Writeln(‘s=’,s:10:3);END.函数课堂练习1.编程找出由键盘任意输入二个整数中的最大数。2.编程找出由键盘任意输入三个整数中的最大数。3.求从键盘任意输入两个自然数的最大约数。4.求从键盘任意输入三个自然数的最大约数。5.求从键盘任意输入两个自然数的最小公倍数。6.用函数求1+2+3……+n的和(n=100)。【上机练习6.1】1.编程求5!+7!+9!+11!的值。2.编程求CRK=K!/(R!(K-R)!)(KR0)3.求正整数2和100之间的完全数。完全数:因子之和等于它本身的自然数,如6=1+2+3;4.如果一个自然数是素数,且它的数字位置经过对换后仍为素数,则称为绝对素数,例如13。试求出所有二位绝对素数5.编写程序计算表达式:Y=x2+SH(x),SH(x)是双曲正弦函数【提示】在Fp中没有SH()函数,需要由用户自已定义,由数学知识知:SH(x)=(ex–e–x)/2。第二节过程在Pascal中,自定义过程与自定义函数一样,都需要先定义后调用。函数一般用于求值,而过程一般实现某些操作,两者的本质区别就是在于:函数有一个值返回,主程序中调用时要有一个相应类型的变量来接收这个值,而过程只是完成某些操作,没有返回值,调用时可以当成完成某项功能的一条命令。过程的说明过程说明的一般格式为:procedure过程名(形式参数表);//过程首部说明部分;begin//以下是过程体语句1…语句nend;说明:①过程首部以关键字procedure开头。②过程名是用户自定义的标识符,只用来标识一个过程,不能代表任何数据,因此不能说明过程的类型。③形参表缺省(当然要同时省去一对括号)时,称为无参过程。④形参表的一般格式形式如下:[var]变量名1:类型;…;[var]变量名n:类型。其中带var的称为变量形参,不带var的称为形参。在函数中,一般都是形参,很少用变量形参(但可以使用)。例如,下列形参表中:(x
本文标题:函数与过程.
链接地址:https://www.777doc.com/doc-2641186 .html