Pascal 过程

  • 过程

    过程是子程序,而不是返回单个值,而是允许获得一组结果。
  • 定义过程

    在Pascal中,使用procedure关键字定义了一个过程。过程定义的一般形式如下-
    语法
    
    procedure name(argument(s): type1, argument(s): type 2, ... );
       < local declarations >
    begin
       < procedure body >
    end;
    
    Pascal 中的过程定义由过程头,局部声明和过程主体组成。过程头由关键字procedure和为过程指定的名称组成。这是过程的所有部分-
    • 参数 -参数建立了调用程序与过程标识符之间的链接,也称为形式参数。过程中的参数规则与函数的规则相同。
    • 局部声明 -局部声明是指标签,常量,变量,函数和过程的声明,它们仅适用于过程主体。
    • 过程主体 -过程主体包含定义过程的语句的集合。应始终将其保留在保留字的开头和结尾之间。这是完成所有计算的过程的一部分。
    以下是名为findMin()的过程的源代码。此过程采用4个参数x,y,z和m,并将前三个变量中的最小值存储在名为m的变量中。变量m通过引用传递(稍后将讨论通过引用传递参数)-
    
    procedure findMin(x, y, z: integer; var m: integer); 
    (* Finds the minimum of the 3 values *)
    
    begin
       if x < y then
          m := x
       else
          m := y;
       
       if z < m then
          m := z;
    end; { end of procedure findMin }  
    
  • 过程声明

    过程声明告诉编译器过程名称以及如何调用该过程。该过程的实际主体可以单独定义。过程声明具有以下语法-
    
    procedure name(argument(s): type1, argument(s): type 2, ... );
    
    请注意,该过程的名称与任何类型都不相关。对于上面定义的过程findMin(),以下是声明-
    
    procedure findMin(x, y, z: integer; var m: integer);
    
  • 调用过程

    在创建过程时,您将定义该过程必须执行的操作。要使用该过程,您将必须调用该过程以执行定义的任务。当程序调用过程时,程序控制将转移到被调用过程。被调用过程执行已定义的任务,并且在到达其最后一个end语句时,它将控制权返回给调用程序。要调用一个过程,您只需要传递所需的参数以及过程名称,如下所示:
    
    program exProcedure;
    var
       a, b, c,  min: integer;
    procedure findMin(x, y, z: integer; var m: integer); 
    (* Finds the minimum of the 3 values *)
    
    begin
       if x < y then
          m:= x
       else
          m:= y;
       
       if z < m then
          m:= z;
    end; { end of procedure findMin }  
    
    begin
       writeln(' Enter three numbers: ');
       readln( a, b, c);
       findMin(a, b, c, min); (* Procedure call *)
       
       writeln(' Minimum: ', min);
    end.
    
    编译并执行并交互上述代码后,将产生以下类似结果-
    
    Enter three numbers:
    99 33 76
    Minimum: 33
    
  • 递归子程序

    我们已经看到一个程序或子程序可以调用另一个子程序。当子程序调用自身时,它称为递归调用,该过程称为递归。为了说明这个概念,让我们计算一个数字的阶乘。n的阶乘定义为-
    
    n! = n*(n-1)!
       = n*(n-1)*(n-2)!
          ...
       = n*(n-1)*(n-2)*(n-3)... 1
    
    以下程序通过递归调用自身来计算给定数字的阶乘。
    
    program exRecursion;
    var
       num, f: integer;
    function fact(x: integer): integer; (* calculates factorial of x - x! *)
    
    begin
       if x=0 then
          fact := 1
       else
          fact := x * fact(x-1); (* recursive call *)
    end; { end of function fact}
    
    begin
       writeln(' Enter a number: ');
       readln(num);
       f := fact(num);
       
       writeln(' Factorial ', num, ' is: ' , f);
    end.
    
    编译并执行交互上述代码后,将产生以下类似结果-
    
    Enter a number:
    4
    Factorial 4 is: 24
    
    以下是另一个示例,该示例使用递归函数为给定数字生成斐波那契数列-
    
    program recursiveFibonacci;
    var
       i: integer;
    function fibonacci(n: integer): integer;
    
    begin
       if n=1 then
          fibonacci := 0
       
       else if n=2 then
          fibonacci := 1
       
       else
          fibonacci := fibonacci(n-1) + fibonacci(n-2);
    end; 
    
    begin
       for i:= 1 to 10 do
       
       write(fibonacci (i), '  ');
    end.
    
    尝试一下
    编译并执行上述代码后,将产生以下结果-
    
    0 1 1 2 3 5 8 13 21 34
    
  • 子程序的参数

    如果子程序(函数或过程)要使用参数,则它必须声明接受参数值的变量。这些变量称为子程序的形式参数。形式参数的行为类似于子程序中的其他局部变量,并在进入子程序时创建并在退出时销毁。调用子程序时,可以通过两种方式将参数传递给子程序:
    • 按值传递调用 - 此方法将参数的实际值复制到子程序的形式参数中。在这种情况下,对子程序内部参数的更改不会对参数产生影响。
    • 按引用传递调用 - 此方法将参数的地址复制到形式参数中。在子程序内部,该地址用于访问调用中使用的实际参数。这意味着对参数所做的更改会影响参数。
    默认情况下,Pascal使用按值调用来传递参数。通常,这意味着子程序中的代码无法更改用于调用子程序的参数。我们在“Pascal 函数”一章中使用的示例程序使用按值调用调用了名为max()的函数。而此处提供的示例程序(exProcedure)使用引用调用来调用 findMin()过程。
    按值传递调用 - 示例
    
    program exCallbyValue;
    var
       a, b : integer;
    (*procedure definition *)
    procedure swap(x, y: integer); 
    
    var
       temp: integer;
    
    begin
       temp := x;
       x:= y;
       y := temp;
    end;
    
    begin
       a := 100;
       b := 200;
       writeln('Before swap, value of a : ', a );
       writeln('Before swap, value of b : ', b );
       
       (* calling the procedure swap  by value   *)
       swap(a, b);
       writeln('After swap, value of a : ', a );
       writeln('After swap, value of b : ', b );
    end.
    
    尝试一下
    按引用传递调用 - 示例
    
    program exCallbyRef;
    var
       a, b : integer;
    (*procedure definition *)
    procedure swap(var x, y: integer);
    
    var
       temp: integer;
    
    begin
       temp := x;
       x:= y;
       y := temp;
    end;
    
    begin
       a := 100;
       b := 200;
       writeln('Before swap, value of a : ', a );
       writeln('Before swap, value of b : ', b );
       
       (* calling the procedure swap  by value   *)
       swap(a, b);
       writeln('After swap, value of a : ', a );
       writeln('After swap, value of b : ', b );
    end.
    
    尝试一下