Ada “如何定义”+&引用;对于记录类型

Ada “如何定义”+&引用;对于记录类型,ada,Ada,我正在尝试用ADA创建一个包。我有三个文件,adb(主程序)、ads(包)和adb(主体包)。我看不到我的主文件和包文件有任何问题。然而,在我的body包中,我很难编写一个函数,将P1和P2的值相加,然后返回其值 我的主要节目: with Ada.Text_IO; use Ada.Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; with Price_Handling;

我正在尝试用ADA创建一个包。我有三个文件,adb(主程序)、ads(包)和adb(主体包)。我看不到我的主文件和包文件有任何问题。然而,在我的body包中,我很难编写一个函数,将P1和P2的值相加,然后返回其值

我的主要节目:

with Ada.Text_IO;                use Ada.Text_IO;
with Ada.Integer_Text_IO;        use Ada.Integer_Text_IO;
with Price_Handling;             use Price_Handling;
procedure Test_Price_Plus is

P1, P2 : Price_Type;  
begin
P1.Dollar:= 19;
P1.Cents:= 50;
P2 := (Dollar => 10, Cents=> 0);
Put("P1 is ");
Put(P1);
New_Line;
Put("P2 is ");
Put(P2); 
New_Line;

Put("If we add P1 and P2, then we get: ");
Put(P1 + P2);
New_Line;
end Test_Price_Plus;
我的包裹:

with Ada.Text_IO;                use Ada.Text_IO;
with Ada.Integer_Text_IO;        use Ada.Integer_Text_IO;
package Price_Handling is

type Price_Type is private;
procedure Get(Item: out Price_Type);
function "+"(Left, Right: in Price_Type) return Price_Type;  -- Left(Dollar), Right(Cents)
private 
type Price_Type is
record
Dollar, Cents: Integer;
end record;
end Price_Handling;
我的包体:

Package Body Price_Handling is 
procedure Put(Item:in  Price_Type) is
begin
Put(Item.Dollar); Put(":");
Put(Item.Cents);
end Put; 
function "+"(Left, Right: in Price_Type) return Price_type is   
begin
  -- Need to write a function that adds P1 and P2 together and return its value
  end "+";

对于新手来说,最简单的方法可能就是创建一个虚拟结果值并返回它:

函数“+”(左、右:在价格类型中)返回价格类型为
结果:价格型;
开始
结果.美元:=左.美元+右.美元;
结果.分:=左.分+右.分;
--如果你的美分高于100,那么我们
--需要增加美元并调整美分
--计数
如果结果.美分>99,则
结果美元:=结果美元+1;
Result.Cents:=Result.Cents-100;
如果结束;
返回结果;
结束“+”;
然而,这是非常薄弱的。您的价格类型不是使用可以保护您免受错误影响的类型设计的。如果你想利用艾达的安全方面,考虑制造一个限制你0到99的美分分型:

子类型分_类型为自然范围0。。99;
这样,如果您发生编程错误并输入大于99或负值的值,那么程序将捕获该值并引发异常。美元也一样。为非负值创建新类型:

subtype$u类型是自然的;
现在更新记录以使用这些类型,并默认初始化它们:

类型价格\u类型为记录
美元:美元类型:=0;
美分:美分类型:=0;
结束记录;
然后,如果您这样做,您可以更新+函数,使用一个虚拟变量来保存美分,以防在将它们相加时超过99

函数“+”(左、右:在价格类型中)返回价格类型为
结果:价格型;
分_与_溢出:自然;
开始
结果.美元:=左.美元+右.美元;
带有溢出的美分:=左.美分+右.美分;
--如果你的美分高于100,那么我们
--需要增加美元并调整美分
--计数
如果美分溢出>99,则
结果美元:=结果美元+1;
Result.Cents:=Cents_,_溢出-100;
其他的
Result.Cents:=带有溢出的Cents\u;
如果结束;
返回结果;
结束“+”;

解决此问题的另一种方法是将价格类型的每个实例的美元和美分转换为美分总数。只需添加两美分的值,然后将结果转换回美元和美分

package Price_Handling is
   
   type Price_Type is private;
   
   function "+" (Left, Right : Price_Type) return Price_Type;
   procedure Get(Item : out Price_type);
   procedure Print(Item : in Price_Type);
private
   
   subtype Cents_Type is Integer range 0..99;
   type Price_Type is record
      Dollars : Natural := 0;
      Cents   : Cents_Type := 0;
   end record;

end Price_Handling;


with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

package body Price_Handling is

   ---------
   -- "+" --
   ---------

   function "+" (Left, Right : Price_Type) return Price_Type is
      function To_Cents ( Item : Price_type) return Natural is
         Temp : Natural := 100 * Item.Dollars + Item.Cents ;
      begin
         return Temp;
      end To_Cents;
      function To_Price(Item : in Natural) return Price_Type is
         Dollars : Natural;
         Cents   : Cents_Type;
      begin
         Dollars := Item / 100;
         Cents   := Item mod 100;
         return (Dollars, Cents);
      end To_Price;
      
   begin
      return To_Price(To_Cents(Left) + To_Cents(Right));
   end "+";

   ---------
   -- Get --
   ---------

   procedure Get (Item : out Price_type) is
      
   begin
      Put("Enter the dollars for the price: ");
      Get(Item.Dollars);
      Put("Enter the cents for the price: ");
      Get(Item.Cents);
   end Get;
   
   -----------
   -- Print --
   -----------
   
   procedure Print (Item : in Price_Type) is
   begin
      Put(Item => Item.Dollars, Width => 1);
      Put (".");
      if Item.Cents < 10 then
         Put ("0");
      end if;
      Put (Item => Item.Cents, Width => 1);
   end Print;
   

end Price_Handling;


with Price_Handling; use Price_Handling;
with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
   P1 , P2 : Price_Type;
begin
   Get(P1);
   Get(P2);
   Put("The sum of P1 and P2 is: ");
   Print(P1 + P2);
   New_Line;
end Main;
另一个示例显示,当两美分的金额总和超过一美元时,美元金额的适当增加是:

Enter the dollars for the price: 10
Enter the cents for the price: 52
Enter the dollars for the price: 3
Enter the cents for the price: 95
The sum of P1 and P2 is: 14.47

向前看,也可以考虑一个十进制定点类型,它不需要强制转换(它不存在于艾达中)或类型转换(它)。所有值都有Integer'Base类型,并且可以自由混合在一起:
Cents\u和\u溢出:=Left.Cents+Right.Cents
Result.Cents:=带有溢出的美分我用不同版本的GNAT检查后调整了答案
Enter the dollars for the price: 10
Enter the cents for the price: 52
Enter the dollars for the price: 3
Enter the cents for the price: 95
The sum of P1 and P2 is: 14.47