ADA程序实例(类型、控制流、转换、简单数学运算等)

以下是ADA实现的质因数分解程序,其等价C#程序可见:

http://topic.csdn.net/u/20111112/18/2bf17a93-862d-458e-91d7-8682dc899315.html


(由于没有专门的ADA代码显示模板,只能选择最相近的Delphi模板,故关键字标识会不正常)

首先是功能单元模块(package)的声明文件(prime-factors-resolver.ads):

with Ada.Containers.Doubly_Linked_Lists; use Ada.Containers;

package prime_factors_resolver is
  -- instantiate a generic package and use its content
  package Int_List is new Doubly_Linked_Lists(Integer);
  use Int_List;

  function resolve(number : Integer) return List;

end prime_factors_resolver;


接下来是功能单元的实现文件(prime-factors-resolver.adb):

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;
use  Ada.Numerics;

package body prime_factors_resolver is
  package Float_Functions is new Generic_Elementary_Functions(Float);
  use Float_Functions;

  function resolve(number : Integer) return List is
    list_of_factors : List;
    list_of_primes : List; -- list of primes encountered so far
    k : Integer := 2;	-- prime number starts from 2
    value: Integer;
  begin
    if number < 2 then
      list_of_factors.Append(number);
      return list_of_factors;
    end if;

    value := number;

    -- see, ada supports this also now in its latest version
    -- originally it had to be Append(list_of_primes, k);
    list_of_primes.Append(k);

    mainloop:	-- named loop for specific quiting
    while true loop
      if value = k then	-- value is k straight
        list_of_factors.Append(k);
        exit mainloop;	-- exit specific loop (in this case the immediate loop)
      elsif value rem k = 0 then	-- value is divisible by k
        Append(list_of_factors, k);
      	value := value / k;
      else 	-- value is greater than and indivisible by k
        declare	-- make use of block to declare block-wide variables
          is_prime: Boolean := true;
          prime_number : Integer;
        begin
          if k = 2 then
            k := 1;	-- go backwards by one for this special case
          end if;
          loop	-- loop to find the prime number next to k
            k := k + 2;

            is_prime := true;
            for prime_cursor in list_of_primes loop
              prime_number := element(prime_cursor);
              if k rem prime_number = 0 then
                is_prime := false;
              	exit;
              elsif prime_number > Integer(Float'Floor(Float(k)**0.5)) then
                exit;
              end if;
            end loop;
            exit when is_prime;	-- this is equivalent to 'until' condition
          end loop;	-- the next prime number found

          list_of_primes.Append(k);
        end;
      end if;
    end loop mainloop;

    return list_of_factors;
  end resolve;

begin
  put_line("Resolver successfull loaded.");

end prime_factors_resolver;


最后是调用这个模块的主程序(main.adb):

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Fixed;  use Ada.Strings.Fixed;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with prime_factors_resolver; use prime_factors_resolver;
use prime_factors_resolver.Int_List;  -- have to be that defined immediately

procedure main is
  user_input : String(1..32) := 32 * " "; -- a way to create string with spaces
  user_input_len : Integer;
  number : Integer;
  list_of_factors : Int_List.List;
  factor : Integer; 	 -- the value of the item the cursor pointing to
  first_factor : Boolean := true;
begin
  
  put("Input a number: ");
  get_line(user_input, user_input_len);
  number := Integer'Value(user_input);	-- a system provided way of conversion

  put(number);
  put(" = ");
  list_of_factors := resolve(number);
  for factor_cursor in list_of_factors loop
    factor := Element(factor_cursor);
    if first_factor then
      first_factor := false;
    else
      put(" * ");
    end if;
    put(factor, 0);	-- 0 to indicate leaving no spaces around the number
  end loop;

end main;


这里面有几点注意,(以前学的时候也可能忽略,有些可能是近期ADA版本的新属性)

1. ADA最新版本支持以对象Instance为主体的方法调用(可以像C#和Java那样用点“.”来访问对象的方法),就像以上的Append方法,但条件是这个方法定义的第一参数(潜在的接入主体)必须是tagged定义的record,即使能了object oriented的ADA数据。例如对Cursor类型的Element方法就不能这样用,因为Cursor没有tagged。

2. ADA中使用一个功能提供者的交互的数据结构(就像函数参数,返回值),其类型需要从这个功能提供者这边直接得到,而不是从源头得到,就像例子中的List。这和C#是不一样的(对我而言我倒更接受ADA这种处理,虽然有时有些麻烦了点)。

3. 泛型包(Generic Package)的实例化要加new关键字。

4. 好多Attribute要记(ADA里的Attribute指一种基于类型的功能方法,他们都是系统内建的(还是可能供用户定义?可能性不大))。

5. ADA的运算符重载的广度肯定在C#之上(但,当然,在C++之下:))。

6. ADA的可带类型限制的泛型定义的广度和表达力极可能完全在C#之上。


从这个例子可以看出ADA十分严谨(我认为它是世界上最严谨的语言),而功能全面超越所有Pascal系语言(除了一些OO特性如多态性需要进一步研究考证),而且有大量的类型定义和处理特性和面向对象特性有待探索。

posted @ 2011-11-13 16:11  quanben  阅读(520)  评论(0编辑  收藏  举报