代码(Ada) 1. Hello, concurrent word

这门课使用Ada语言,感觉国内的相关资料比较少,所以我会一边上传代码一边讲解语法。

下面这段代码是用来实现两个算式,让他们同时运行,即2个程序并行。

with Ada.Text_IO; use Ada.Text_IO;
procedure means is
   type number is digits 5;  --表示该type的精确度为五位小数 
   type numbers is array (Positive range <>) of number;
   Test_numbers : constant numbers := (10.0, 20.0, 40.0, 30.0);
   n : constant number := 6.0;
   task Arithmetic_Mean;  --声明并运行一个task 
   task Harmonic_Mean; -- 声明并运行一个task

  -- 以下是一个task的body
   task body Arithmetic_Mean is
      A_Mean : number := 0.0;

   begin
      for i in Test_numbers'Range loop
         A_Mean := A_Mean + Test_numbers (i);
      end loop;
      A_Mean := A_Mean / n;
      Put ("Arithmetic_Mean : ");
      Put (number'Image (A_Mean));
      New_Line;
   end Arithmetic_Mean;

   -- 以下是一个task的body
   task body Harmonic_Mean is
      H_Mean : number := 0.0;
   begin
      for i in Test_numbers'Range loop
         H_Mean := 1.0 / (H_Mean + (1.0 / Test_numbers (i)));
      end loop;
      H_Mean := H_Mean * n;
      Put ("Arithmetic_Mean : ");
      Put (number'Image (H_Mean));
      New_Line;
   end Harmonic_Mean;

-- 这个是主程序的运行内容,即这段代码有3个task
begin
   null;
end means;

语法:
3个keyword :Last, Range,First。
Last:对于scalar subtype ,它表示该数范围内的最后一个值。
对于一个数组,它表示该数组的最后一个index的值。
Frist:同上,都是第一个值。
Range:对于scalar subtype ,它表示有效值的范围。
对于一个数组,它表示index的范围。
T'Range == T'First .. T'Last

这里有一个主程序,大多数情况下,它都没有内容,但是他一定是最后一个结束的程序,因为一旦他结束了,整个程序也就结束了。


下面这段代码是实现一个队列,个人感觉原理都差不多,故编写起来还算简单

package body Queue_Pack_Private is

   procedure Enqueue (Item : Element; Queue : in out Queue_Type) is

   begin
      if Is_Full (Queue) then
         raise Queue_overflow;
      end if;

      Queue.Elements (Queue.Free) := Item;
      Queue.Free     := Queue.Free + 1;
      Queue.Is_Empty := False;
   end Enqueue;

   procedure Dequeue (Item : out Element; Queue : in out Queue_Type) is
   begin
      if Is_Empty (Queue) then
         raise Queue_underflow;
      end if;

      Item := Queue.Elements (Queue.Top);
      Queue.Top := Queue.Top - 1;

      if Is_Empty (Queue) then
         Queue.Is_Empty := True;
      end if;
   end Dequeue;

   function Is_Full (Queue : Queue_Type) return Boolean is
     (not Queue.Is_Empty and then Queue.Top = Queue.Free);

   function Is_Empty (Queue : Queue_Type) return Boolean is
     (Queue.Top = Queue.Free);

end Queue_Pack_Private;

在这个队列判断full or empty的时候,个人感觉有些问题,没有按照队列判满的常规进行。(部分代码老师给的,所以不能改)


下面这段代码在Queue的基础上改成了一个可以被overload的stack。

generic
   type Element is private;
   Stack_Size : Positive := 10;

package Queue_Pack_Private is

   type Queue_Type is limited private;

   procedure Enqueue (Item :     Element; Queue : in out Queue_Type);
   procedure Dequeue (Item : out Element; Queue : in out Queue_Type);

   function Is_Empty (Queue : Queue_Type) return Boolean;
   function Is_Full  (Queue : Queue_Type) return Boolean;

   Queue_overflow, Queue_underflow : exception;

private
   type Marker is new Integer range 1 .. Stack_Size; -- attention
   type List is array (Marker) of Element;
   type Queue_Type is record
      Top, Free : Marker  := Marker'First;
      Is_Empty  : Boolean := True;
      Elements  : List;
   end record;
end Queue_Pack_Private;

with Queue_Pack_Private;
with Ada.Text_IO;        use Ada.Text_IO;

procedure Queue_Test_Private is
   package Queue_Pack_Character is new Queue_Pack_Private (Element => Character, Stack_Size => 20);
   use Queue_Pack_Character;

   Stack : Queue_Type;
   Current_Item : Character;

begin
   Enqueue (Item => 'x', Queue => Stack);

   Enqueue (Item => 'y', Queue => Stack);

   Enqueue (Item => 'z', Queue => Stack);

   Dequeue (Current_Item, Stack);

   Put_Line ("Current_Item:" & Current_Item);

   Put_Line ("Stack is" & (if Is_Empty (Stack) then "" else " not") & " empty on exit");

exception
   when Queue_underflow => Put ("Queue underflow");
   when Queue_overflow  => Put ("Queue overflow");
end Queue_Test_Private;

上面的代码主要是说明了重载的使用方法。先在package的声明中定义它为一个可以overload的package,

generic
   type Element is private;
   Stack_Size : Positive := 10;

然后在调用这个package的时候对其重载。

package Queue_Pack_Character is new Queue_Pack_Private (Element => Character, Stack_Size => 20);
   use Queue_Pack_Character;

notice:有if 就必须要有else

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容