codecamp

Ada程序包的概述

概述(Overview)

    多子程序封装在一个文件里过于庞大,且分类不清,这时就使用了程序包(package),作为一种分组机制,将子程序归类封装成独立的单元。Ada 的程序包机制主要受 Pascal 及 70 年代时的软件工程技术影响。当时很主要的一项革新就是软件包的概念。软件包使一个大程序分离成了多个单元,使软件维护更加方便,可重用性也更高,是结构化编程思想中必不可少的一部份。

    软件包并不关心程序是如何运行的,而是在于理解程序是如何构成的以及维护性。Ada 的程序包是定义一堆相关实体(如数据类型、运算符、子程序)的最基本单元,也是使用最常用的编译单元之一。本章里我们介绍程序包的常见用法,更多的内容,如类属程序包,请参见后面的章节。


程序包的声明(Package Declaration)

    程序包一般分为两部份,声明部分和执行部份。声明部份声明子程序、变量等实体,他们通常被称为资源;而执行部份则是声明部分中实体的实现。它们的扩展名一般情况下分别为 ads 和 adb。为了省力点,我们就直接将上一章的overload 做个处理,将"+"和Put封装在程序包内,这样程序包说明如下:

000 --filename:overload.ads
001 package Overload is
002    type Vector is array (1 .. 5 ) of Integer;
003    function "+"(left,right:Vector) return Vector;
004    procedure Put (Item : Vector) ;
005 end Overload;

    从这个例子,我们应该知道了程序包说明的格式:

package packgae_name is
  statements;
end package_name;

    statemets就是数据类型、变量、常量、子程序的声明。


程序包的主体部份(Package Body)

    仅仅有说明部份,程序包还没什么用处,还要有它的主体部份,即说明部份的具体实现。主体部份可以包含创建数据类型、子程序、变量、常量。它的格式为:

package body packgae_name is
    statements1;
[begin]
    statements2;
end package_name;

    statements1 是创建子程序、数据类型、变量、常量的语句,一般情况下是说明部份的具体实现;[begin]是可选的,它后面的statement2 是程序包的初始化语句,在主程序执行前开始执行。

    所以上例 overload 的主体部分为:

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

002 package body Overload is
003    function "+"(left,right:Vector) return Vector is
004        result : Vector ;
005    begin
006       for i in left'range loop
007           result(i) := left(i) + right(i);
008       end loop;
009       return result;
010    end "+";
011    procedure Put (Item : Vector) is
012    begin
013       for i in Item'range loop
014           Put (Item(i));
015       end loop;
016    end Put;
017 end Overload;

这里我们没有使用可选的 [beginstatement2,因为没有必要做一些初始化操作。下面是一些注意点:

1.主体部分内的资源不能被其它程序包所引用,会引起编译错误。

2.假如好几个程序包都有初始化语句,执行顺序是不确定的。

3.所有说明部份内的资源可以被其主体部份直接使用,无须 with 和 use 语句。


程序包的使用(Using Package)

     如同我们先前使用 Ada.Text_IO 一样,使用程序包要使用 with 和 useuse 可以不用,但这样的话使用程序包麻烦很多,如 Put ,就要使用 Ada.Text_IO.Put这种详细写法;use 使编译器自动在软件包中寻找相匹配的子程序和其它资源。现在将 overload 的主程序给出:

000 -- filename: main.adb
001 with Overload; use Overload;

002 procedure Main is 
003    a,b,c:Vector;
004 begin
005    a := (1,2,3,4,5);
006    b := (1,2,3,4,5);
007    c := a + b;
008    Put (c);
009 end Main;

     编译 main.adb,overload.adb,overload.ads 所得的程序和以前的效果也一样。

     一般情况下,with 和 use 语句在程序的首部,但 use 语句也可以在程序内部(with 语句则不能),如:

000 -- filename: main.adb
001 with Overload;

002 procedure Main is 
003    use Overload;
004    a,b,c:Vector;
005 begin
006    a := (1,2,3,4,5);
007    b := (1,2,3,4,5);
008    c := a + b;
009    Put (c);
010 end Main;

      这种用法很常见,特别是使用类属程序包时。以后我们会见到这方面的其它实例。

       使用软件包时要注意一下变量、常量等名称的问题,如果有相同的名称,就需要详细写出所期望的资源名称,如程序包 Ada.Text_IO 的 Put 要写为 Ada.Text_IO.Put。如果在 Overload 的声明部份也加一个变量a(2,3,5,6,8),则声明部份为:

000 --filename:overload.ads
001 package Overload is
002    type Vector is array (1 .. 5 ) of Integer;
003     a: Vector := (2,3,5,6,8); 
004    function "+"(left,right:Vector) return Vector;
005    procedure Put (Item : Vector) ;
006 end Overload;

   同时我们希望主程序将两个不同的a分别与b相加,则 Overload 中的 a 要表示为 Overload.a,主程序变为:

00 -- filename: main.adb
001 with Overload; use Overload;
002 with Ada.Text_IO; use Ada.Text_IO;

003 procedure Main is 
004    a,b,c:Vector;
005 begin
006    a := (1,2,3,4,5);
007    b := (1,2,3,4,5);
008    c := a + b;
009    Put (c); 
010    New_Line;
011    c := Overload.a + b; -- Overload.a 表示程序包 Overload中的变量 a 
012    Put (c);
013    New_Line; 
014 end Main;

   明确资源的位置在很多地方都是需要的,都是为了防止相同名称引起混淆。


Ada子程序的调用
Ada私有类型和有限专用类型
温馨提示
下载编程狮App,免费阅读超1000+编程语言教程
取消
确定
目录

关闭

MIP.setData({ 'pageTheme' : getCookie('pageTheme') || {'day':true, 'night':false}, 'pageFontSize' : getCookie('pageFontSize') || 20 }); MIP.watch('pageTheme', function(newValue){ setCookie('pageTheme', JSON.stringify(newValue)) }); MIP.watch('pageFontSize', function(newValue){ setCookie('pageFontSize', newValue) }); function setCookie(name, value){ var days = 1; var exp = new Date(); exp.setTime(exp.getTime() + days*24*60*60*1000); document.cookie = name + '=' + value + ';expires=' + exp.toUTCString(); } function getCookie(name){ var reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); return document.cookie.match(reg) ? JSON.parse(document.cookie.match(reg)[2]) : null; }