1、函数和过程,1、计算机程序设计和问题求解的基本思想是将一个复杂问题分解成更小、更简单的容易处理的子问题。为此提出了结构化程序设计思想 。子程序是实现结构化程序设计的主要手段之一。,2、子程序:是指本身不能单独执行,需要其他程序调用才能执行的程序。如Pascal提供的标准函数和过程等。与子程序相对应的是我们所设计的程序称为主程序。 程序是从主程序开始执行的,通过主程序去调用子程序。 一个完整的Pascal程序可以包含一个主程序和若干个子程序。 子程序常见的两种形式:函数和过程,一、函数(把完成某种计算的子程序定义为函数,每调用 一次产生一个结果),2、自定义函数:只能在定义它的程序中被调用。 一
2、般定义形式:,function 函数名(形式参数表):类型标识符;局部变量说明部分begin语句;语句end;,1、标准函数:直接输入函数名和参数进行调用即可。可用在不同的程序中。可随时进行调用。,函数首部,函数体,例1:设计一个求累加和的函数。输入一个正整数,然后计算从1到此数的累加和。,Function sum(n:integer):integer; Var s,I:integer; Begins:=0;for I:=1 to n do s:=s+I;sum:=s; end;,函数首部和函数体的说明见教材P76和P77,例如:要调用上面的函数,主程序如下: Var x:integer; b
3、eginreadln(x); write(sum(x); End.,3、函数调用,函数名(实在参数表) 详细说明见教材P77下和P78上,例2:计算如图示多边形的面积,分析:求五边形的面积可以变成求3个三角形面积之和。在这个程序中要计算三次三角形面积,为程序简单起见,可将计算三角形面积定义为函数,然后在主程序中调用3次,并相加得到五边形的面积。三角形的面积可用海伦公式计算。,Function area(a,b,c:real):real; Var p:real; Beginp:=(a+b+c)/2;area:=sqrt(p*(p-a)*(p-b)*(p-c); End; Var b1,b2,b3
4、,b4,b5,b6,b7,s:real; Beginreadln(b1,b2,b3,b4,b5,b6,b7);s:=area(b1,b5,b6)+area(b2,b6,b7)+area(b3,b4,b7); Writeln(s=,s:8:2); End.,二、过程,2、自定义过程一般定义形式:课本P81,procedure 过程标识符(形式参数表);变量说明部分begin语句部分end;,过程首部,过程体,方括号内为可选部分,在过程首部的过程标识符之后若无可选部分, 称为无参过程;否则称为带参过程。,过程与程序有相同的块结构形式。,在过程说明中的说明部分可以对过程内使用的常量、变量、行号、类型
5、、过程 和函数进行说明,但它们的作用范围(辖域)只能在过程内,离开过程后,其 所占的内存释放。另外,过程可以通过(形式参数表)与主程序交换信息,即 调用时可以使用不同数据替换这些参数。,1、标准过程:如读语句read( );写语句write( )等,procedure fiveline;var i:integer;beginfor i:=1 to 5 dowritelnend;,procedure nlines(n:integer);var i:integer;beginfor i:=1 to n dowritelnend;,无参过程,输出5个空行,带参过程,输出n个空行,过程调用,过程名(实
6、在参数表),实在参数若有,是用逗号隔开的变量或表达式,他们必须 与形式参数顺序一一对应,个数相同,类型一致,而实参的名 字与形参取名无关,如:procedure lowterm(var n,d:integer);,实参只有一个,第二个实参是实型,而对应的形参是整型,过程调用是一个独立的语句,当执行到该语句时,则将实参中的信息传送 给相应的形参(若有的话),然后转去执行过程说明中的语句,执行完毕 后返回到调用位置,例3:定义一个打印由“”组成的三角形的过程,然后,在主程序中输入行数,并调用该过程输出三角形。, ,Procedure sjx(x:integer); Var I,j:integer;
7、 Beginfor I:=1 to x dobeginfor j:=1 to I do write();writeln;end; End; Var a:integer; Beginread(a);sjx(a); End.,函数与过程的区别(课本P83P84),1、保留字不同:function与procedure,2、过程说明允许没有形式参数表,3、在函数说明的首部必须指出函数的数据类型,4、在函数体中,必须有对函数名进行赋值的语句,5、过程本身可以单独作为程序语句,练习1:分别用函数和过程计算S=1/7!+1/9!+1/13!,Procedure f(n:integer;var fac:rea
8、l);var i:integer;k:longint;begink:=1;for i:=2 to n do k:=k*i;fac:=1/kend;,Var s1,s2,s3:real; beginf(7,s1);f(9,s2);f(13,s3);s1:=s1+s2+s3;writeln(s1) end.,Function f(n:integer):real;var i:integer;k:longint;begink:=1;for i:=2 to n do k:=k*i;f:=1/kend;,Var s:real;begins:=f(7)+f(9)+f(13);writeln(s)end.,三
9、、参数传递,形参有4种:值参数、变量参数、过程参数、函数参数,形式参数表中前无var,后有类型的参数,形式参数表中前有var后有类型的参数,change(sin(x)+0.5); change(1.0); change(x); change(i);,若将过程首部改为:procedure(var y:real);,形参是值参:过程或函数被调用时,系统为每个值参开辟临时 存储单元,然后将对应实参的值赋给值参。由于值参与实参是 不同的存储单元,所以过程体中对值参的改变不会影响实参, 数据的传送是单向的,当流程返回到调用程序时,值参所占的 存储单元被释放。,形参是变量参数:进入过程体前,系统将实参的存
10、储地址传送 给形参,过程体执行期间,对变量参数的操作就是对相应实参 的操作,从而达到调用函数与被调函数之间互相传送数据的目 的。,参考课本P84P86,例,Program transmit;var a,b:integer;procedure p(var x:integer;y:integer);beginx:=x+5;y:=y+5;writeln(x=,x,y=,y)end;begina:=3;b:=3;p(a,b);p(a,b);writeln(a=,a,b=,b)end.,x=8 y=8,x=13 y=8,a=13 b=3,阅读课本例69 P86,四、标识符的作用域,在主程序中说明的常量、
11、类型、变量、过程名等标识符,它们 的作用域是整个程序,故称为全程量。而在过程或函数中说明 的常量、类型、变量、参数以及嵌套在其内的过程名等标识符, 作用域是说明它的过程或函数分程序之内,在之外不能使用, 这些标识符成为局部量。,如果在过程或函数中局部量与全程量(或非局部量)同名,则 阻碍了过程或函数对同名全程量(或非局部量)的访问。,全局量与局部量分析,结果,11,22,12,五、嵌套,一个函数或过程可能要求调用另一个函数或过程, 我们称这种调用为函数与过程的嵌套,Program nest;procedure outer1;procedure inner(z:real);begin.end;i
12、nnerbeginend;outer1procedure outer2;beginend;begin主程序end.,调用原则(函数同过程):,1、外层的主程序或过程可以调用相邻 内层的过程,但不允许隔层调用 2、内层可以调用外层过程 3、同一层的过程可以相互调用,但要 遵守“向前说明”的原则,一、教材P94P96的应用实例要看会。,二、练习1、设计一个过程,计算圆的面积。在主程序中输入一个半径值,然后调用该过程,并输出圆的面积。2、读入正整数n,利用函数求2到n之间所有的素数。3、编写一个函数,根据参数指定的n,计算出函数值x,计算公式如下:,并在主程序中调用此函数,计算X函数值(保留六位小数
13、),4、在程序中定义一函数digit(n,k),它能分离出整数n从右边数第K个数字,并在主程序中调用此函数。如:digit(31859,3)=8, digit(2076,5)=0,参考答案: 1、设计一个过程,计算圆的面积。在主程序中输入一个半径值,然后调用该过程,并输出圆的面积。,const pi=3.1415926; var r,s:real; procedure yuan(x:real;var y:real);beginy:=pi*x*x;end; beginreadln(r);yuan(r,s);writeln(s=,s:6:2); end.,2、读入正整数n,利用函数求2到n之间所有
14、的素数。,var n,i:integer; function sushu(x:integer):boolean; var j:integer;b:boolean; beginj:=2;while x mod j0 do j:=j+1;if j=x then sushu:=true else sushu:=false; end; beginreadln(n);for i:=2 to n doif sushu(i) then write(i:5); end.,3、编写一个函数,根据参数指定的n,计算出函数值x,,var n:integer; function f(m:integer):real;
15、var i:integer;t:real; begini:=1;while i=2*m-1 dobegint:=t+1/i;i:=i+2;end;f:=t; end; beginreadln(n);writeln(f(n):12:6); end.,4、在程序中定义一函数digit(n,k),它能分离出整数n从右边数第K个数字,并在主程序中调用此函数。如:digit(31859,3)=8, digit(2076,5)=0,var x:longint;i:integer; function digit(n:longint;k:integer):integer; var j:integer; beg
16、inj:=trunc(exp(k-1)*ln(10);digit:=(n div j) mod 10; end; beginreadln(x,i);writeln(digit(x,i); end.,6、向前引用,所谓向前引用,是指把被调用的尚未说明的过程首部写在任何调用之前,即在一个过程或函数的定义说明之前,先给出这个过程或函数的首部,并用forward保留字暂代过程体。而它的详细定义说明将在引用之后给出,且首部只写子程序名而省去参数部分。例:,procedure q(形参表);forward; Procedure p(形参表);beginq(实参表);end; Procedure q;不带参
17、数beginp(实参表);end;,7、递归,递归形式一般有两种间接递归和直接递归。,间接递归子程序A调用子程序B,子程序B又调用子程序A,在现实生活中,通过间接递归计算两个并列函数或过程的情 况并不多见,比较多的递归方式是直接递归。,直接递归子程序要求自己调用自己,function fac(n:integer):integer;beginif n=0 then fac:=1else fac:=n*fac(n-1);end;fac,这个函数说明的最大优点是fac(n)的解的 表达简明,程序结构紧凑。这种从问题定 义出发构造程序解的方法最便于人们阅读 和理解。但问题是,递归子程序的执行过 程比较
18、复杂,子程序的状态变化比较难掌 握。以fac(3)为例,它的执行流程如图,一般来说,递归子程序在调用本身前应有条件语句控制何时继 续递归,何时结束递归,这个条件语句就是递归边界。例如 fac函数体中的“if n=0 then fac:=1”。,例:(hanoi tower)有三个圆柱A,B,C。n个圆盘按照由小至 大的顺序摞在A柱上。如何以最少次数将圆盘从A柱移至C柱。 输出方案,移动必须满足三个条件:1、能利用A,B,C三个圆 柱;2、一次只能搬动一个圆盘;3、小的圆盘只能往大的圆盘上摞,分析,move(n,a,b,c),练1:快速排序,算法描述,练2:输入一个十进制的整数(-3276732
19、767),求相应的二进制、八进制和十六进制的值。,练3:输入一个凸多边形的n个顶点坐标,求凸多边形的面积。,练4:(数据查找)给定一组数据,查找其中一个符合条件的数据。,折半查找,前提,数据已排序,例:15个整数:12 15 17 24 28 32 45 67 89 145 167 178 211 235 269,http:/www.99dyw.co/ 九九电影网 http:/www.99dyw.tv/ 九九电影网 www.youhuijuan.co 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 www.avttt2015.info 天堂网2014 www.avttv2017.info 天堂网2014 www.avttv2017.org 天堂网2014 天堂网2014 天堂网2014 www.avttv2018.org 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014 天堂网2014,