220 likes | 353 Views
过程与函数二. 在结构化程序设计中,不但要求程序要采用顺序、分支和循环这几种基本结构,同时,在整个程序设计过程中,要求程序具有模块化. 先回顾一下. 子程序 能使程序的结构清晰、层次分明,增强程序的可读性,使程序易于调试和维护。. 函数. 子程序. 过程. 模块化. 求 n! 的函数 fac. 回顾函数的定义. function fac(n:integer):longint; var k:integer; t :longint; begin t:=1;
E N D
在结构化程序设计中,不但要求程序要采用顺序、分支和循环这几种基本结构,同时,在整个程序设计过程中,要求程序具有模块化在结构化程序设计中,不但要求程序要采用顺序、分支和循环这几种基本结构,同时,在整个程序设计过程中,要求程序具有模块化 先回顾一下 子程序能使程序的结构清晰、层次分明,增强程序的可读性,使程序易于调试和维护。 函数 子程序 过程 模块化
求n!的函数fac 回顾函数的定义 function fac(n:integer):longint; var k:integer; t:longint; begin t:=1; for k:=2 to n do t:=t*k; fac:=t; end; {endfac} 子程序内所用的类型、常量、变量只在子程序内有效,退出子程序后,该单元被释放。
计算s:=1!+2!+3!+……5!的函数 Program hs_exam1; Var s :longint; function fac(n:integer):longint; var k,t:integer; begint:=1; for k:=2 to n do t:=t*k; fac:=t; end; { 将计算结果值赋给函数,返回调用处 } begin S:=fac(1)+fac(2)+fac(3)+fac(4)+fac(5) ; write(‘s=‘,s); end,. 函数的调用
通过函数我们可以得到一个计算结果,然而有时我们希望通过一个子程序得到多个计算结果,或者仅仅只想让子程序完成一项任务(比如输出固定格式的结果)而不需要返回任何结果时,我们通常用过程来解决问题。通过函数我们可以得到一个计算结果,然而有时我们希望通过一个子程序得到多个计算结果,或者仅仅只想让子程序完成一项任务(比如输出固定格式的结果)而不需要返回任何结果时,我们通常用过程来解决问题。 我们以前用过的读语句read、readln,写语句write、writeln,实际上都是过程语句,由于他们由Pascal语言系统预先说明的,故称为标准过程。
自定义过程的格式: Procedure 过程名(形参表); 局部变量说明; begin 语句1; 语句2; … end; 过程首部 过程体
n!用过程fa来定义。 思考:n!的结果存放在哪里? Procedure fa(n:integer); var k:integer; begin t:=1; for k:=2 to n do t:=t*k; end; t 在主程序中说明,为全局变量。 n!的结果是如何回传给主程序的? 是通过t带回主程序的。 是数据传递的又一种方式 注意: 不能给过程名赋值,过程名不能代表任何数据。
Procedure fa(n:integer); 过程调用 fa(5); 函数的调用方式是出现在表达式中,而过程调用是通过一条独立的过程调用语句来实现的。 一般形式为:<过程名>(<实在参数表>); 调用过程通过给出一个过程名,并用实在参数去代替形式参数。 说明: ①实参的个数、类型必须与形参一一对应; ②对应于值形参的实参可以是表达式,对应于变量形参的实参只能是变量; ③调用过程的步骤是:计算实参的值,传送给对应的形参,接着执行过程体,最后返回调用处继续执行。
求 1!+2!……10! 比较一下 Program jc; Var i:integer; t,s:longint; Procedure fa(n:integer); var k:integer; begin t:=1; for k:=2 to n do t:=t*k; end; Begin s:=0; for i:=1 to 10 do begin fa(i); s:=s+t; end; write(s); End. Program jc; var i:integer;s:longint; function fac(n:integer):longint; var k:integer; t:longint; begin t:=1; for k:=2 to n do t:=t*k; fac:=t; end; begin s:=0; for i:=1 to 10 do s:=s+fac(i); write(s); End.
求三角形面积的函数 function area(a,b,c:real):real; var p:real; begin p:=(a+b+c)/2; area:=sqrt(p*(p-a)*(p-b)*(p-c)); end;
一个求三角形面积的过程area。 Procedure area(a,b,c:real; var mj:real); var p:real; begin p:=(a+b+c)/2; mj:=sqrt(p*(p-a)*(p-b)*(p-c)); end; 过程中数据传送的另一种方式:变量形参 a、b、c、m四个参数,a、b、c为值形参,参数m前面有var,是变量形参。该过程被调用后,由变参mj将结果传回调用程序。
b2 b1 b6 b3 b5 b7 b4 过程调用: 过程名:实在参数表; 例:用过程编写程序求如图所示的五边形面积。 Program dbs; var b1,b2,b3,b4,b5,b6,b7,s,sum,real; Procedure area(a,b,c:real; var mj:real); var p:real; begin p:=(a+b+c)/2; mj:=sqrt(p*(p-a)*(p-b)*(p-c)); end; begin 三角形的面积通过变参mj传回主程序。 readln(b1,b2,b3,b4,b5,b6,b7); area(b1,b5,b6,s); sum:=0; area(b2,b6,b7,s); sum:=sum+s; sum:=sum+s; area(b3,b4,b7,s); sum:=sum+s; writeln(‘sum=‘,sum:10:3); end.
比较 Program mjg; var b1,b2,b3,b4,b5,b6,b7,s,sum,real; Procedure area(a,b,c:real; var mj:real); var p:real; begin p:=(a+b+c)/2; mj:=sqrt(p*(p-a)*(p-b)*(p-c)); end; begin readln(b1,b2,b3,b4,b5,b6,b7); sum:=0; area(b1,b5,b6,s); sum:=sum+s; area(b2,b6,b7,s); sum:=sum+s; area(b3,b4,b7,s); sum:=sum+s; writeln(‘sum=‘,sum:10:3); end. Program mjh; var b1,b2,b3,b4,b5,b6,b7,s:real; function area(a,b,c:real):real; var p:real; begin p:=(a+b+c)/2; area:=sqrt(p*(p-a)*(p-b)*(p-c)); end; Begin readln(b1,b2,b3,b4,b5,b6,b7); s:=area(b1,b5,b6)+area(b2,b6,b7) +area(b3,b4,b7); writeln(‘s=’,s:10:3); End.
Procedure area(a,b,c:real; var mj:real); function area(a,b,c:real):real; 过程 函数 过程和函数的主要区别: 完成一系列的数据处理,或与计算无关的各种操作 操作 往往求一个函数值 函数有类型,最终要将函数值传送给函数名。 无 结果类型 由独立的过程调用语句来完成 函数调用出现在表达式中 调用方式 s:=area(b1,b5,b6) area(b2,b6,b7,s); 返回值的方法 通过变参将运算的结果传给调用程序 函数值是通过函数名传回调用程序
过程、函数的数据传递 在主程序调用子程序时,调用程序(主程序)将数据传递给被调用的过程或函数(子程序),而当子程序运行结束后,结果又可以通过函数名、变参传给调用程序;当然也可以用全局变量等形式实现数据的传递。
变量及其作用域(全局变量与局部变量) 例1读程序写结果。 m为全局变量。 Program ex1-5(input,output); var m:integer; procedure test1; begin m:=100; end; begin m:=5; writeln(‘m=‘,m); test1; writeln(‘m=‘,m); end. 全局量的作用域有两种情况: 1、在全局变量和局部变量不同名时,其作用域是整个程序。 2、在全局变量和局部变量同名时,全局变量的作用域不包含同名局部变量的作用域。 m=5 结果为: m=100
例2读程序写结果。 Program ex1-5b(input,output); var m:integer; procedure test2; var m:integer; begin m:=100; end; begin m:=5; writeln(‘m=‘,m); test2; writeln(‘m=‘,m); end. M是局部变量,结果被屏蔽,它不影响到全程变量m的值。 m=5 结果为: m=5
全局变量:在主程序中被说明 作用域:整个程序; 局部变量:在子程序中被说明 作用域:主程序及其下级的程序。 全程量的作用域分两种情况: ①当全程量和局部量不同名时,其作用域是整个程序。 ②当全程量和局部量同名时,全程量的作用域不包含局部量的作用域。 当局部变量所在子程序被调用时,局部变量才被分配有效的存储单元;当返回调用程序时,局部变量所占的存储单元就被释放。
练一练: Program ex1-2(input,output); var x,y:integer; procedure change; var x:integer; begin x:=2; y:=2; writeln(x,y); end; begin x:=1; y:=1; writeln(x,y); change; writeln(x,y); end. 结果为: • 1 • 2 • 1 2
值参 实参 过程 变参 过程 实参 写出下列两个程序的运行结果 1 2 1 2 1 22 1 这两个程序唯一的区别是ex1中将x、y作为值形参,而 ex2中将x、y作为变量形参 ;因此在ex2中对x、y的修改实际上是对调用该过程时与它们对应的变量a、b的修改,故最后,a、b的值为2、1。而ex1中调用swap过程时,只是将a、b的值传递给x、y,之后在过程中的操作与a、b无关。
完成变量a,b的交换 Program pjh; Var x,y:integer; Procedure swap(var x,y:integer); var t:integer; begin t:=x;x:=y;y:=t; end; Begin x:=10;y:=20; writeln(‘q’,x,y); swap; writeln(‘h’,x,y); End; Program pjh; Var x,y:integer; Procedure swap; var t:integer; begin t:=x;x:=y;y:=t; end; Begin x:=10;y:=20; writeln(‘q’,x,y); swap; writeln(‘h’,x,y); End; 变量形参 全局变量
1 A 65 B 66 C D E F G H I J K L M N O P 第十二届全国青少年信息学奥林匹克联赛初赛试题 Program ex403; Const NN=7; Type Arr1=array[0..30] of char; var s:arr1; k,p:integer; function fun1(s:arr1; a:char;n:integer):integer; var j:integer; begin j:=n; while (a<s[j])and(j>0) do dec(j); fun1:=j; end; function fun2(s:arr1; a:char; n:integer):integer; var j:integer; begin j:=1; while (a>s[j])and(j<n) do inc(j); fun2:=j; end; begin for k:=1 to NN do s[k]:=chr(ord('A')+2*k+1); k:=fun1(s,'M',NN)+fun2(s,'M',NN); writeln(k); end. Ord(x)求字符对应的ASCII码 如:Ord(‘A’)=65 Chr(x)求ASCII码对应得字符 如:Chr(65)=’A’ S[1] S[2] S[3] S[4] S[5] S[6] S[7] D F H J L N P dec(j) j=j-1 inc(j) j=j+1