在某些程序中,如果一些具有相同功能的程序段在程序的不同位置多次出现,一般将这些程序段,单独写成子程序。
引入子程序后,可以将较复杂的问题分解成若干较小易处理的子问题,且更重要的是是程序结构清晰、层次分明,增强程序可读性。
前面学过一些标准函数(如abs(x)、sqr(x)等和标准过程(如readln、write等)。
一、函数
如果一个子程序执行后能够返回其结果值,那么它就可以用于表达式中,称这种子程序称为函数。
1
、函数定义格式如下:
function 函数名(形式参数表):函数类型; { 函数首部 }
局部变量说明;
begin
语句;
function 函数名(形式参数表):函数类型; { 函数首部 }
局部变量说明;
begin
语句;
……
函数体
end;
例1、计算n!的函数
function fac(n:integer):integer;
var k,m:integer;
begin
m:=1; for k:=2 to n do m:=m*k;
例1、计算n!的函数
function fac(n:integer):integer;
var k,m:integer;
begin
m:=1; for k:=2 to n do m:=m*k;
fac:=m; {
将计算结果值赋给函数,返回调用处 }
end;
函数定义一般由函数首部和函数体两部分组成
end;
函数定义一般由函数首部和函数体两部分组成
函数首部以保留字function开头,函数名为自定义的标识符、括号内为函数形参表(函数的自变量)。例题中求n!的函数定义,函数名是fac;它有一个值参数n为整数型,n的初值来自主程序的调用;函数值的数据类型为整数型。
如函数没有自变量,则形参表可以缺省,为无参函数。
函数的类型,即函数值的数据类型。
函数值将通过函数名传送回调用的程序。因此,函数体中每次求值至少要有一条语句对函数名赋值。如函数fac:=m,计算求得一个值,返回时就把这个值带回调用的地方。
2
、函数的调用
自定义函数只限于在定义它的程序中使用。函数调用形式为:
函数名(实在参数表);
函数调用必须出现在表达式中,且调用的自定义函数在之前已定义过;
实参表是若干由逗号分隔的参数。在调用函数时,实参应有确定的值,实参将值赋给形参,因此,实参的个数、类型应与形参一一对应。
函数调用的步骤是先在调用程序中计算实参的值,传送给对应的形参,然后执行函数体,最后将函数值返回调用程序处。
如函数定义后未被调用,则该函数将不会被执行。
例2、编程,对6到100的偶数验证哥德巴赫猜想:任一个大于等于6的偶数总可以分解为两个素数之和。输出每个数是哪两个素数之和。
var a,i,j:integer;
function fect(m:integer):boolean;
var k,s:integer;
begin
s:=trunc(sqrt(m)); k=2;
while (m mod k<>0)and (k<=s) do k:=k+1;
if k>s then fect:=true else fect:=false;
end;
begin
for i:=6 to 100 do
for j:=3 to trunc(i/2) do
if fect(j) and fect(i-j) then writeln(i,'=',j,'+',i-j)
end.
例3、求正整数a和b之间的完全数(a<b)。完全数是指它的因子之和等于它本身,如6=1+2+3。古人只知道最前面的四个完全数为6、28、496、8128、而第30个完全数是在1986年9月被发现的!
例3、求正整数a和b之间的完全数(a<b)。完全数是指它的因子之和等于它本身,如6=1+2+3。古人只知道最前面的四个完全数为6、28、496、8128、而第30个完全数是在1986年9月被发现的!
完全数有许多有趣的性质,例如:
1.
它们都能写成连续自然数之和:6=1+2+3, 28=1+2+3+4+5+6+7, 496=1+2+3+4+……+31, 8128=1+2+3+4+……+127;
2.
它们的全部因数的倒数之和都是2。
1/1+1/2+1/3+1/6=2
1/1+1/2+1/4+1/7+1/(14)+1/(28)=2
1/1+1/2+1/4+1/8+1/(16)+1/(31)+1/(62)+1/(124)+1/(248)+1/(496)=2
1/1+1/2+1/4+1/7+1/(14)+1/(28)=2
1/1+1/2+1/4+1/8+1/(16)+1/(31)+1/(62)+1/(124)+1/(248)+1/(496)=2
var a,b,i,j,n: integer;
c:array[1..20] of integer;
function fac(x:integer):boolean;
var k,sum:integer;
begin
sum:=1; n:=0;
for k:=2 to x div 2 do
if x mod k=0 then begin n:=n+1; c[n]:=k; sum:=sum+k end;
if x=sum then fac:=true else fac:=false;
end; {
将计算结果值true 或false赋给函数fac,返回调用处 }
begin {
主程序 }
write('input a,b:');
repeat readln(a,b) until (a>0) and (b>0) and (a<b);
for i:= a to b do
if fac(i) then {
调用函数fac,如返回值为true,输出完全数 }
begin
write(i,'=1');
for j:=1 to n do write('+',c[j]);
writeln
end;
end.
输入:2 1000
输出:6=1+2+3
28=1+2+4+7+14
496=1+2+4+8+16+31+62+124+248