在PASCAL语言中 函数和过程有什么区别 要具体的

如题所述

函数与过程
主要作用在于使程序结构清晰,养成模块化解决问题的习惯。
当然也可以用在解决循环、递归方面的一些问题。

1.函数
PASCAL给我们提供了一些标准函数,我们不用了解这些函数如何求出来的,只管直接调用它们,挺方便的。如正弦函数,余弦函数,算术平方根......有了这些函数,我们觉得很省事。如:求SIN(1)+SIN(2)+...+SIN(100)=?这个程序我们可以这样编写:

例1
PROGRAM e1(input,output);
VAR i:integer;
s:real;
BEGIN
s:=0;
for i:=1 to 100 do
s:=s+sin(i);
writeln('s=',s);
END.
在这个程序里,我们直接用到了正弦函数,至于SIN(1),SIN(2)如何求出来的我们不需过问,只管直接用它的结果便是了。

我们来看看下面一个例子:求:1!+2!+3!+....+10!=?
如果要编写程序,我们看到求阶乘的操作要执行10次,只不过每次所求的数不同。我们想:不至于编写10遍求阶乘的程序吧。我们希望有一个求阶乘的函数,假设为JS(X),那么我们就可以这样求这道题了:

例2
PROGRAM e1(input,output);
VAR i:integer;
s:real;
BEGIN
s:=0;
for i:=1 to 10 do
s:=s+js(i);
writeln('s=',s);
END.

现在的问题是:TURBO PASCAL没提供JS(X)这样一个标准函数,这个程序是通不过的。如果是PASCAL的标准函数,我们可以直接调用,如TRUNC(X),LN(X),SQRT(X)....而PASCAL提供给我们的可供直接调用的标准函数不多。没关系,我们编写自己的函数!

1.2 函数的编写

自己编写一个函数,它的格式如下:
FUNCTION 函数名(形式参数表):函数类型;
VAR 函数的变量说明;
BEGIN
函数体
END;

我们来分析一下,一个函数的编写可分成三部份:一是函数首部,即第一个语句。它必须以FUNCTION开头,函数名是自己取的,取名的原则是便于记忆,和文件名的取名规则类似。形式参数(简称形参)表以标识符的形式给出,相当于函数中的自变量。参数可以有多个,也可以有多种类型。不同类型的参数之间用";"隔开,同类型的参数如有多个,则用","隔开,在其后得加上说明。如:

FUNCTION A1(A,B,C:INTEGER;D,E,F:REAL):REAL;

在最后,函数属于哪种类型,还得表示出来。在本例中,该函数为实型。
第二部分是函数的变量说明部分,对在本函数中将要用到的变量作类型说明,这一点和以前学的变量一样。如果程序不用变量,则此部分也可省掉。
第三部分是函数体,本函数的功能实现就在于此,编写的语句就在里面。

例3 编写一求阶乘的函数。

我们给此函数取一名字就叫JS。
fUNCTION js(n:integer):longint;
var i:integer;
s:longint;{数字比较大,所以要用长整型}
begin
s:=1;
for i:=1 to n do
s:=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叫值参。而SQRT(X),LN(Y)中的X,Y叫形参。

1.3 函数的调用
自定义的函数在调用前要先说明,在主程序中的位置如下:
PROGRAM 程序名(INPUT,OUTPUT);
VAR 主程序变量说明;
FOUNCTION 函数名(形参表):函数类型;
VAR 函数变量说明;
BEGIN
函数体
END
BEGIN
主程序
END.

在主程序中,我们把函数的全部说明放在主程序的变量说明和程序体之间,然后在主程序的执行部分就可以直接调用自定义函数了。注意:在函数的说明部分,我们要用形参,但在程序的执行部分调用自定义函数时,就得用值参了。
例4 利用前面定义的阶乘函数,求5!, 9!。
PROGRAM e59(input,outout);
VAR a1,a2:longint;

FUNCTION js(n:integer):longint;
var i:integer;
s:longint;
begin
s:=1;
for i:=1 to n do
s:=s*i;
js:=s;
end;

BEGIN
a1:=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!。另外,函数不能单独使用,一定要结合主程序才能运行。

如果是求1!+2!+3!+...+10!,则只需把主程序改成:
A1:=0;
FOR J:=10 TO 10 DO
A1:=A1+JS(J);
WRITELN(A1);

在例4中,主程序的变量A1,A2叫全程变量,它们除了主程序外,还可以在函数中出现;在函数说明中用到的变量I,S则是局部变量,只能在函数部分使用,一旦出了函数则失去意义;别外要注意:全程变量和局部变量尽量不要同名。

例5 任意输入10组三角形的三边,求其面积。
已知三角形的三边,是可以求出面积的。我们可以定义一个已知三角形三边求其面积的函数,设为AREA(a1,a2,a3)。

PROGRAM e5(inmput,output);
VAR a,b,c,s:real;
i:integer;

FUNCTION area(a1,a2,a3:real):real;
var s1,d:real;
begin
d:=(a1+a2+a3)/2;
s1:=Sqrt(d*(d-a1)*(d-a2)*(d-a3));
area:=s1;
end;

BEGIN
for i:=1 to 10 do
begin
writeln('input a,b,c');
readln(a,b,c);
if (a+b<=c) or (a+c<=b) or(b+c<=a)
then writeln('data error!')
else writeln('s=',area(a,b,c));
end;
END.

在函数说明中,如果形参的个数不止一个,那么在程序中调用函数的实参个数一定要与形参的个数一致,第一个实参对应第一个形参,第二个实参对应第二个形参.......次序不能调。

例6 定义一个函数CHECK(N,D),让它返回一个布尔值。如果数字D在整数N的某位中出现则送回TRUE,否则送回FALSE。例如:
CHECK(325719,3)=TRUE;
CHECK(77829,1)=FALSE;

PROGRAM e6(input,output);
VAR a,b:integer;

FUNCTION check(n,d:integer):boolean;
var f:boolean;
e:integer;
begin
f:=false;
while (n>0) and (not f) do
begin
e:=n mod 10;
n:=n div 10;
if e=d then f:=true;
end;
check:=f;
end;

BEGIN
writeln('input n,d');
read(a,b);
writeln(check(a,b));
END.

2.过程

过程和函数一样,也是子程序。一个过程对应一个需要完成的任务。PASCAL中提供了不少标准过程,如:READ,WRITE,GET,NEW,PUT.......这些标准过程在程序中可以直接调用。但仅仅这些标准过程还不能满足我们的需要,我们还要自己定义过程,就象函数一样。但函数必须以值的形式返回,而过程不一定返回一个值,只是执行一个任务而已;函数只能返回一个值,而过程可以返回不止一个值。所以函数不能取代过程。

2.1 过程的定义
过程定义的格式如下:

PROCEDURE 过程名(形式参数);
VAR 过程的变量说明;
BEGIN
过程体
END;

对该格式说明如下:

一个过程也分为三部分,1.过程的首部。过程必须以PROCEDURE开头,过程名的取名规则和函数名一样,括号里面是形式参数,如形参不止一种,则中间用";"隔开,同类形参如不止一个,则中间用","隔开。另:有时侯过程不用加参数。2.过程的说明部分,用VAR开头,它只能对过程中的变量进行说明,同样是局部变量。另:如果过程不用变量,则可将说明部分省略。3.过程体。它是过程的执行部分。
我们来定义一个打印由"*"组成的矩阵的过程,该矩阵四行五列。

例7
PROCEDURE print;
var i,j:integer;
begin
for i:=1 to 4 do
begin
for j:=1 to 5 do
write('*');
writeln;
end;
end;

该过程就没有参数,直接执行打印一个固定矩阵的任务,而且也没返回值。

例7 定义一个求N!的过程。
PROCEDURE js(n:integer);
var s:longint;
i:integer;
begin
s:=1;
for i:=1 to n do
s:=s*i;
writeln(n,'!=',s);
end;

在该过程中,它的值的返回形式和函数不一样:函数是由函数名返回,而过程不是由函数名返回的;在过程的首部不用对过程的类型进行说明。

2.3 过程的调用
自定义过程在程序调用之前要先说明,过程的说明就在主程序的执行语句之前。其格式如下:

PROGRAM 程序名(INPUT,OUTPUT);
VAR 主程序的变量说明;

PROCEDURE 过程名(形式参数表);
VAR 过程的变量说明;
BEGIN
过程体
END;

BEGIN
主程序体
END.

例8.任意输入10个三角形的三边,用过程把其面积求出。
我们把求一个已知三边的三角形的面积定义一个过程,对比一下和例5有什么不同。

PROGRAM e5(inmput,output);
VAR a,b,c,s:real;
i:integer;

PROCEDURE area(a1,a2,a3:real);
var s1,d:real;
begin
d:=(a1+a2+a3)/2;
s1:=Sqrt(d*(d-a1)*(d-a2)*(d-a3));
writeln('s=',s1);
end;

BEGIN
for i:=1 to 10 do
begin
writeln('input a,b,c');
readln(a,b,c);
if (a+b<=c) and (a+c<=b) and (b+c<=a)
then writeln('data error!')
else area(a,b,c);
end;
END.

我们看到:过程的调用和函数不同。函数不能作为独立的一个语句使用,而过程可以。函数的值是由函数名返回的,而过程不能。
现在我们提出一个要求:用过程求出1!+2!+3!+....10!=?
求N!的问题我们在例7已写出来,但阶乘的结果是在过程里用WRITE语句输出的,不能用累加语句把结果求出来。那么,怎样用过程将类似的问题求出来?这就得用到变量参数。

2.4变量参数
在过程定义的语句中,有个参数表,在参数表中,除了前面我们已用的值参,还有变量参数。变量参数的作用是:它可以作为过程的出口参数。我们可以把过程中求出的结果用变量参数输出到过程外,在过程外面可以调用该参数,因此,该参数是全局变量。其格式上的区别是在变量参数前加上VAR即可。
那么我们现在来求1!+2!+3!+....+10!=?

例9
PROGRAM e9(input,output);
VAR j:integer;
s,m:longint;

PROCEDURE js(n:integer;var m:longint);
var i:integer;
begin
m:=1;
for i:=1 to n do
m:=m*i;
end;

BEGIN
s:=0;
for j:=1 to 10 do
begin
js(j,m);
s:=s+m;
end;
writeln('s=',s);
END.

在本例中。我们看到,过程JS中用到了变量参数M,在过程中定义为LONGINT类型;而在主程序的变量说明中也得对变量参数M说明为同种类型LONGINGT。于是,在过程中和主程序中都可以用该变量了。我们在调用这类过程时,在括号中要写上所有的参数,但用不着写上参数的类型和VAR了。

3.5 函数和过程的区别

过程和函数都为子程序,但也有区别:
1. 标识符不同。函数的标识符为FUNCTION,过程为PROCEDURE。
2. 函数中一般不用变量参数,用函数名直接返回函数值;而过程如有返回值,则必须用变量参数返回。
3. 函数在定义时一定要进行函数的类型说明,过程则不进行过程的类型说明。
4. 函数在调用时不能作为一个单独语句使用,而过程在调用时必须作为单独语句使用。
5. 过程可以只执行一个任务而没有计算的结果,而函数则必须返回一个计算值。

例10.任意输入一个整数,将它变成字符串输出。如:输入数34567,打印出字符"34567"。要求用过程的方法实现。
PROGRAM E10(input,output);
var i,k:integer;
s:string;

PROCEDURE n_c(n:integer;var s:string);
var l:inTeger;
begin
l:=abs(n);
s:='';
repeat
s:=char((l mod 10) +ord('0'))+s;
l:=l div 10;
until l=0;
if n <0 then s:='-'+s;
end;

BEGIN
for i:=1 to 10 do
begin
writeln('input k');
readln(k);
n_c(k,s);
writeln('the string is:',s);
end;
END.
温馨提示:答案为网友推荐,仅供参考
第1个回答  2012-02-07
有的可以相互转化、函数有返回值、
就像sqrt、inc等都是函数、
对比看过程像val等、
自己百度一下可能得到更多、
纯手打、】
第2个回答  2012-02-06
函数有返回值,过程没有。
其他一样。
第3个回答  2012-02-06
函数有返回值,过程没有。