Ada子程序的调用

2018-11-20 10:00 更新

调用子程序(Calling Subprograms)

    调用子程序最简单的方式就是按照子程序声明的格式调用,如前例的procedure swap(A:Integer;B:Integer),只要填入的参数是Integer类型,便能直接使用 swap (A,B)。注意调用子程序时参数之间用“,”隔开;同类型的参数在声明时也可简化,如procedure swap(A,B:Integer)。但使用参数时还有下列几种特殊情况.

有名参数(Named Parameter)

    我们也可以不按照参数顺序调用子程序。如调用 swap 也可以这样: swap(B => Y, A => X),这时是使用有名参数,明确声明每个变量的值,可以不按照子程序声明中的参数顺序赋值。这样的做的话可读性是好了一点,比较适合参数较多的情况。

    如果将有名参数和位置参数一起混用,只需遵守一条规则:位置参数在有名参数前面。因此 swap 的调用有以下几种情况:

swap(x , y);

swap(A => x , B => y);

swap(B => y , A => x);

swap(x, B => Y);

    上述四种情况是一样的。下列两种情况是非法的:

swap(y, A => x);---不合法

swap(A => x , y); ---不合法

默认参数值(Default Parameter Values )

    在声明某个子程序时,我们也可以使参数具有默认值,如下例:

000 -- filename:putlines.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure putlines is 
004    procedure putline(lines: integer:=1) is<> 005 begin
006        for count in 1..lines loop
007           New_Line;
008        end loop;
009    end putline;
010    Line :Integer;
011 begin
012    Put ("Print Lines :"); Get (Line);
013    putline;
014 end putlines;

    实际上[012]可有可无,因为调用输出行函数 putline 时,没用参数。而 putline 在声明时赋予了参数 lines 一个默认值 1,这样的话如果调用 putline 没用参数,就以 1 作为参数值。上例也就只输出一个空行。如果putline有参数,如putline(Line),则输出的行数取决于 Line 的数值。

重载(Overload)

子程序重载

    实际上通过先前的一些例子,细心的朋友可能发现,过程 Put 能处理不能类型的参数,不像 C 下的 printf 要选择输出类型,这就涉及到子程序重载:只要参数不一样,子程序可以有相同的名称。如在程序包Ada.Text_IO里的两个过程:

procedure Put (Item : in Character);

procedure Put (Item : in String);

   编译器会自动选择合适的子程序,如果Put后面的参数为 Character类型,则调用procedure Put (Item : in Character);为 String 类型,则调用procedure Put (Item : in String)。这样在用户层上使用子程序简便了许多,很多常见的子程序:Get,Put_Line,Line, Page都是这样实现的----虽然在预定义程序包内针对不同参数都有一个子程序与之相对应,用户却只要记住一个名称就可以了。

运算符重载

    运算符重载应该说时时刻刻都在----不同的数据类型都拥有相同的运算符:+,-,*,/等。它的原理和子程序重载是一样的,在 Ada 里,运算符也是通过子程序形式来实现。下面就给出一个“+”和 put 重载的例子:

000 -- filename: overload.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure overload is
004    type Vector is array (1 .. 5 ) of Integer;
005     a, b, c :Vector;

006    function "+"(left,right:Vector) return Vector is
007        result : Vector ;
008    begin
009       for i in left'range loop
010           result(i) := left(i) + right(i);
011       end loop;
012       return result;
013    end "+";

014    procedure Put (Item : Vector) is
015    begin
016       for i in Item'range loop
017           Put (Item(i));
018       end loop;
019    end Put;
020 begin
021    a := (1,2,3,4,5);
022    b := (1,2,3,4,5);
023    c := a + b;
024    Put (c);
025 end overload;

    上例为了简化问题,有些实际中应该有的代码去除了----如检测所操作数的类型。但其它类型的运算符和重载子程序实现原理也和上例一样。

分离子程序(Separating Subprogram)

    Ada 还允许子程序分成多个部份,而不是像以前的例子一样都塞在同一文件里,如将上例分成两个文件:

第一个文件:

000 -- filename: overload.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

003 procedure overload is
004    type Vector is array (1 .. 5 ) of Integer;
005     a, b, c :Vector;
006    function "+"(left,right:Vector) return Vector is
007        result : Vector ;
008    begin
009       for i in left'range loop
010           result(i) := left(i) + right(i);
011       end loop;
012       return result;
013    end "+";
014    procedure Put (Item : Vector) is separate;
015 begin
016    a := (1,2,3,4,5);
017    b := (1,2,3,4,5);
018    c := a + b;
019    Put (c);
020 end overload;
第二个文件:
000 --filename:overload-put.adb
001 separate (overload)     -- *注意结尾没有分号;
002 procedure Put (Item : Vector) is 
003 begin
004    for i in Item'range loop
005       Put (Item(i));
006    end loop;
007 end Put;

      这个程序和先前那个完全一样,只是"分了家"而已。这样分离程序有时能更好的分解程序的任务,使程序结构更为清楚。注意一下overload.adb的[014] 和 overload-put.adb的 [001],这两句就是分离子程序的主要语句。

子程序的内嵌扩展(Inline Expansion of Subprograms)

  子程序可以在调用地点被内嵌扩展,以提高程序效率,它的格式为:

pragma Inline(name);

  如果 name 是一个可调用的实体,子程序或类属子程序(见第11章),那么 pragma Inline 指示在所有调用该实体的地方要求对该实体进行内嵌扩展。这在封装其它语言的接口时,使用的比较多,以提高效率。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号