Ada子程序概述
概述 (Overview)
一个程序是由一个或更多的子程序组成,以一个主过程(main procedure)为根本,主过程类似与 C 下的 main 函数。子程序包括过程(proceudre)和函数(function)两类,两者区别在于,过程没有返回值,而函数有返回值。
子程序,包括函数和过程,以及下一章所讲述的程序包,是构成 Ada 程序的基础。Ada 提供了一些和 C、Pascal 不同的新特性,如重载、参数模式、分离程序等。
过程(Procedure)
过程我们以前已经见过了,但那些都是主过程(main procedure),即程序的主体部体,作用和C下的 main 函数相似。一般情况下,Ada 程序的主程序名应当和该主程序所在的文件名相同。过程的声明格式如下:
procedure procedure_name (parameter_specification);
它的执行部份则为:
procedure procedure_name (parameter_specification) is
declarations;
begin
statements;
end procedure_name ;
procedure_name 为该过程的名称;parameter_specification 是这个过程所要使用的参数,是可选的;declarations 是声明一些局部的新类型、变量、函数、过程;statements 则是该过程要执行的语句。
下例创建一个比较两数大小,并输出较大值的过程:
procedure compare (A:Integer; B :Integer) is
begin
if A > B then
Put_Line ("A > B");
elsif A = B then
Put_Line ("A = B");
else
Put_ine ("A <B");
end if;
end compare;
下例则是完整的程序:
000 -- filename:comp.adb;
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure comp is
004 procedure compare (A:Integer; B :Integer) is
005 begin
006 if A > B then
007 Put_Line ("A > B.");
008 elsif A = B then
009 Put_Line ("A = B.");
010 else
011 Put_ine ("A < B.");
012 end if;
013 end compare;
014 X,Y:Integer;
015 begin
016 Put ("Enter A:"); Get (X);
017 Put ("Enter B:"); Get (Y);
018 compare (X,Y);
019 end comp;
通过上例,对过程的用法应该会有基本的了解了。因为 compare 的执行部分是在 comp 内部,所以我们无须给出单独的 compare 声明,如果要加一句"procedure compare (A:Integer; B :Integer);",程序还是老样子。声明部份和执行部份一般在使用程序包时分离。其中Put_Line,Get也都是预定义的过程。
函数 (Function)
函数和过程也很像,只是它还要有返回值,和 C 很相似,也用 return 来返回函数值。声明格式为:
function function_name (parameter_specification) return return_type;
执行部份为:
function function_name (parameter_specification) return return_type is
declarations;
begin
statements;
return return_value;
end function_name ;
function_name 为该函数的名称;parameter_specification 是这个函数所要使用的参数,是可选的;declarations 是声明一些局部的新类型、变量、函数、过程;statements则是该函数要执行的语句。return 返回一个数据类型为return_type的return_value。
将上一节的 comp 程序改动一下:
000 -- filename:comp.adb;
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure comp is
004 function compare (A:Integer; B :Integer) return Integer is
005 begin
006 return (A - B);
007 end compare;
008 X,Y,Result:Integer;
009 begin
010 Put ("Enter A:"); Get (X);
011 Put ("Enter B:"); Get (Y);
012 Result := compare (X,Y);
013 case Result is
014 when Integer'First..-1 => Put_Line (" A < B.");
015 when 0 => Put_Line (" A = B.");
016 when 1..Integer'Last => Put_Line (" A > B.");
017 when others => null;
018 end case;
019 end comp;
上例应该还能说明函数的特点。因为函数是返回一个值,所以在变量声明中赋予初始值时,也可用函数作为所要赋的值,如返回当前时间的 Clock 函数,可以直接在初始化某变量时作为要赋的值:Time_Now :Time:= Clock。与过程一样,在上述情况下,单独的函数声明可有可无。还有一点就是函数、过程的嵌套,上面两个例子就是过程包含过程,过程包含函数,可以无限制的嵌套下去---只要编译器别出错。
参数模式(Parameter Mode)
在上面的例子中,我们对函数或过程的参数并没做什么修饰,只是很简单的说明该参数的数据类型,但有时候,我们要设置参数的属性---函数和过程是否能修改该参数的值。一共有三种模式:in,out,in out。
in 模式
默认情况下,函数和过程的参数是 in 模式,它表示这个参数可能在子程序中被使用,但值不能被子程序改变。如我们写一个略微像样点的swap函数:
000 filename:swap.adb
001 with Ada.Text_IO; use Ada.Text_IO;
002 with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
003 procedure Swap is
004 procedure Swap ( A: in Integer;B: in Integer) is
005 Temp :Integer;
006 begin
007 Temp := A; A:= B; B :=Temp;
008 end Swap;
009 X,Y:Integer;
010 begin
011 Put ("Enter A:"); Get (X);
012 Put ("Enter B:"); Get (Y);
013 Put ("After swap:"); New_Line;
014 swap(X,Y);
015 Put ("A is "); Put (X); New_Line;
016 Put ("B is "); Put (Y); New_Line;
017 end Swap;
上例的程序是无法编译通过的,因为Swap的两个参数 A 和 B 都是 in 模式,在这个子过程中无法修改X,Y的值,也就无法互换这两个值。这时就要使用 in out 模式的参数。
in out 模式
in out 模式表示该参数在这个子程序中既可修改又可使用。如只要将上例的[004]改为:procedure Swap ( A: in out Integer,B: in out Integer) is;该程序便能编译通过,运行正常。
out 模式
单纯的 out 模式表示该参数在这个子程序中可以修改,但不能使用。如求和的 add 过程:
procedure Add (Left ,Right : Integer; Result : out Integer) is
begin
Result := Left + Right;
end Add;
这个过程没问题,但假如还有个输出过程为:
procedure PutResult ( Result : out Integer) is
Temp : Integer := Result;
begin
Put (Temp);
end PutResult;
则会产生问题,虽然编译可能通过,但结果是不定的,最起码不是所指望的结果,因此 out 模式的参数不能赋值给其它变量。单独的 out 模式一般也不会出现。