首页 PASCAL教学 PASCAL教程 PASCAL练习题 基础知识 常用算法 阶段测试 初赛试题 复赛题库 FP错误代码 留言板
 
第一章 简单程序
第一节 程序结构和基本语句
第二节 顺序结构程序与基本数据类型
第二章 分支程序
第一节 条件语句与复合语句
第二节 情况语句与算术标准函数
第三章 循环程序
第一节 程序结构和基本语句
第二节 Repeat 循环
第三节 While 循环
第四章 函数与过程
第一节 函数
第二节 自定义过程
第五章 自定义数据类型
第一节 数组与子界类型
第二节 二维数组与枚举类型
第三节 集合类型
第四节 记录类型和文件类型
第五节 指针类型与动态数据结构
第六章 程序设计与基本算法
第一节 递推与递归算法
第二节 回溯算法
第七章 数据结构及其应用
第一节 线性表
第二节 队列
第三节 栈
第四节 数组
第八章 搜索
第一节 深度优先搜索
第二节 广度优先搜索
第九章 其他常用知识和算法
第一节 图论及其基本算法
第二节 动态规划
   

第二节 自定义过程

自定义函数通常被设计成求一个函数值,一个函数只能得到一个运算结果。若要设计成能得到若干个运算结果,或完成一系列处理,就需要自定义“过程”来实现。

[4.3] 把前面[例2.2 (输入三个不同的整数,按由小到大排序)改为下面用自定义过程编写的Pascal程序:

Program  exam43;

Var a,b,c: integer;

Procedure  Swap (var x,y: integer);            {自定义交换两个变量值的过程 }

Var t  : integer;

Begin                                          {过程体}

  t:=x; x:=y; y:=t                            {交换两个变量的值

end;

 

Begin                                           {主程序}

  Write('input a,b,c=');

  Readln(a,b,c);

  if ab then swap (a,b);                     {调用自定义过程}

  if ac then swap (a,c);

  if bc fhen swap (b,c);

  Writeln (a:6, b:6, c:6);

  Readln

End.

程序中Procedure Swap是定义过程名,从作用来看,过程与函数是相似的,都能将复杂的问题划分成一些目标明确的小问题来求解,只不过函数有值返回而过程则没有。自定义过程的一般格式如下:

Procedure 过程名 (形式参数表);      {过程首部}

     局部变量说明部分;

     begin

       语句部分;                       {过程体部分}

     end;

 

[4.4]如果一个自然数除了1和本身,还有别的数能够整除它, 这样的自然数就是合数。例如15,除了115,还有35能够整除,所以15是合数。14,15,16是三个连续的合数,试求连续十个最小的合数。

解:从14,15,16三个连续合数中可看出,它们正好是两个相邻素数1317 之间的连续自然数,所以求连续合数问题可以转化为求有一定跨度的相邻两个素数的问题。因此,求连续十个最小的合数可用如下方法:

①从最小的素数开始,先确定第一个素数A;

②再确定与A相邻的后面那个素数B;(作为第二个素数)

③检查A,B的跨度是度否在10 以上,如果跨度小于10,就把B 作为新的第一个素数A,重复作步骤②;

④如果AB跨度大于或等于10,就打印AB之间的连续10个自然数,即输出 A+1, A+2, A+3 ,  A+10

Pascal程序:

Program  exam44;

var a,b,s,n: integer;

    yes: boolean;

procedure sub(x: integer;var yy: boolean);          {过程:求x是否为素数 }

var k,m: integer;                                   { yy逻辑值转出 }

begin

  k:=trunc(sqrt(x));

  for m:=3 to k do

  if odd(m) then

     if x mod m=0 then yy:=false;

end;

 

begin                                       {主程序 }

  b:=3;

  repeat

    a:=b;                                  {a 为第一个素数 }

    repeat

    yes:=true;

  inc(b,2);                               {ba后面待求的素数}

    sub(b,yes);                            {调用SUB过程来确认b是否为素数 }

    if yes then s:=b-a;                     {如果b是素数,则求出跨度s  }

      until yes;

    until s > = 10;

    for n:=a+1 to a+10 do

       write(n:6);

    writeln;

    readln

  end.

程序中的过程SUB,用来确定b是否为素数。过程名后面圆括号内的变量是形式参数,简称为形参。过程SUB(x: integer; Var yy: boolean) 中的x是值形参,而前面冠有Varyy是变量形参。值形参只能从外界向过程传入信息,但不能传出信息;变量形参既能传入又能传出信息。本程序过程SUB中的x是由调用过程的实在参数b传入值,进行处理后,不需传出;而yy是把过程处理结果用逻辑值传出,供调用程序使用。

试把[例4.3]程序中的过程 SWAP(Val x,y: integer),将x,y前面的Var去掉,就变成了纯粹的值形参,就不能将过程所处理的结果传出去,也就无法得到处理后的结果,通过运行程序比较,可以非常明显地看到值形参和变量形参的区别。

    调用过程的格式为:   过程名(实在参数表) ;

调用过程名后面圆括号内的实在参数与定义过程的形参表必须相对应,调用过程相当于一个独立语句,可单独使用。

 

[例4.5]将合数483的各位数字相加(4+8+3=15,如果将483分解成质因数相乘:  483=3*7*23,把这些质因数各位数字相加(3+7+2+3),其和也为15。即某合数的各位数字之和等于它所有质因数的各数字之和。求500以内具有上述特点的所有合数。

解:①设n为所要求的合数,让n1500间循环做以下步骤;

    ②用t1t2分别累计合数nn的质因数的各位数字之和,初值均为0

    ③调用过程SUB3进行非素数判定,以布尔变量yes的真假值判定是否,yes的初值为true,如果为 (not true)非素数,就做步骤④,⑤,⑥;否则取新的n值,重复步骤③;

    ④调用SUB1,求n的各数字之和,传送给t1

    ⑤调用SUB2,求n的各质因数,对于每个质因素都通过SUB1求它各位数字之和,将所有各质因数字传送给t2

    ⑥如果t1=t2(各位数字之和等于它所有质因数的各数字之和),则输出此n

PASCAL程序:

program exam45;

var n,t1,t2,tatol: integer;

    yes: boolean;

procedure sub1(x:integer; var t:integer);           {过程:分离x的各位数字 }

begin                                               {并求各位数字之和 }

repeat

    t:=t+x mod 10;

    x:=x div 10;

  until x=0

end;

 

procedure sub2(x: integer; var t: integer);       {过程:分解质因数 }

var xx,tt:integer;

begin

  xx:=2;

  while x>1 do

  if x mod xx=0 then

begin

        tt:=0;

        sub1(xx,tt);

        t:=t+tt;

        x:=x div xx

      end

    else inc(xx)

end;

 

procedure sub3(x: integer;var yy: boolean);      {过程:判断x是否为素数 }

var k,m: integer;

begin

  k:=trunc(sqrt(x));

  for m:=2 to k do

    if x mod m=0 then yy:=false;

end;

 

begin                                                    {主程序}

   for n:=1 to 500 do

     begin

       t1:=0;t2:=0;

       yes:=true;

       sub3(n,yes);                   {调用过程求素数 }

       if not yes then                 {如果非素数就… }

         begin

           sub1(n,t1);                 {调用过程求n的各位数字之和 }

           sub2(n,t2);                 {调用过程求n的各质因数的数字之和 }

           if t1=t2 then write(n:6);                   {打印合格的合数 }                               

         end

     end;

   readln

end.

 

程序定义了三个过程SUB1SUB2SUB3,其中SUB2过程中又调用了SUB1。在过程中定义的变量或参数,只在本过程内部使用有效。这些变量称为局部变量。如SUB2中的xx只在SUB2中使用,属于局部变量。

 

习题:4.2

1.输入自然数n,求前n个合数(非素数),其素因子仅有23,或5

2.自然数a的因子是指能整除a的所有自然数,但不含a本身。例如12的因子为:1,2,3,4,6。若自然数a的因子之和为b,而且b的因子之和又等于a,则称a,b为一对“亲和数” 。求最小的一对亲和数。

3.求前n个自然数的平方和,要求不用乘法。例如:3的平方不用3*3,可用3+3+3

4.试用容积分别为17升、13升的两个空油桶为工具,从大油罐中倒出15升油来,编程显示出具体的倒油过程。

5.如果一个数从左边读和从右边读都是同一个数,就称为回文数。例如6886就是一个回文数,求出所有的既是回文数又是素数的三位数。

6. 任何大于2的自然数都可以写成不超过四个平方数之和。如:

              8=2222      14=122232 

由键盘输入自然数N2 < N < 2000) ,输出其不超过四个平方数之和的表示式。


© 版权所有 桐乡市高级中学计算机组 王建献 2005-
制作与维护:
桐高计算机组 王建献 邮箱:omnislash2000@163.com
建议使用:800*600分辨率,IE5.0以上版本浏览器