So definieren Sie "+" für einen Datensatztyp

Oct 12 2020

Ich versuche, ein Paket in ADA zu erstellen. Ich habe drei Dateien, adb (Hauptprogramm), ads (Paket) und adb (Body-Paket). Ich kann keine Probleme mit meinen Haupt- und Paketdateien sehen. In meinem Body-Paket habe ich jedoch Probleme beim Schreiben einer Funktion, die die Werte von P1 und P2 addiert und dann ihren Wert zurückgibt.

Mein Hauptprogramm:

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;

Mein Paket:

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;

Mein Paketkörper:

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 "+";

Antworten

5 Jere Oct 12 2020 at 04:15

Der einfachste Weg für Neulinge besteht wahrscheinlich darin, einfach einen Dummy-Ergebniswert zu erstellen und diesen zurückzugeben:

function "+"(Left, Right: in Price_Type) return Price_type is  
   Result : Price_Type; 
begin
   Result.Dollars := Left.Dollars + Right.Dollars;
   Result.Cents   := Left.Cents   + Right.Cents;
   
   -- If your cents are higher than 100, then we 
   -- need to increment dollars and adjust the cents
   -- count
   if Result.Cents > 99 then
      Result.Dollars := Result.Dollars + 1;
      Result.Cents   := Result.Cents - 100;
   end if;

   return Result;
end "+";

Dies ist jedoch sehr schwach. Ihr Price_type wird nicht mit Typen entworfen, die Sie vor Fehlern schützen können. Wenn Sie die Sicherheitsaspekte von Ada nutzen möchten, sollten Sie einen Cents-Subtyp festlegen, der Sie auf 0 bis 99 beschränkt:

subtype Cents_Type is Natural range 0 .. 99;

Wenn Sie auf diese Weise einen Programmierfehler machen und einen Wert über 99 oder einen negativen Wert eingeben, wird dieser vom Programm abgefangen und eine Ausnahme ausgelöst. Gleiches gilt für Dollar. Erstellen Sie einen neuen Typ für nicht negative Werte:

subtype Dollars_Type is Natural;

Aktualisieren Sie nun Ihren Datensatz, um diese Typen zu verwenden, und initialisieren Sie sie standardmäßig:

type Price_Type is record
   Dollars : Dollars_Type := 0;
   Cents   : Cents_Type   := 0;
end record;

Wenn Sie dies tun, können Sie die + -Funktion aktualisieren, um eine Dummy-Variable zu verwenden, um die Cent zu halten, falls Sie beim Addieren über 99 gehen.

function "+"(Left, Right: in Price_Type) return Price_type is  
   Result : Price_Type; 
   Cents_With_Overflow : Natural;
begin
   Result.Dollars      := Left.Dollars + Right.Dollars;
   Cents_With_Overflow := Left.Cents + Right.Cents;
   
   -- If your cents are higher than 100, then we 
   -- need to increment dollars and adjust the cents
   -- count
   if Cents_With_Overflow  > 99 then
      Result.Dollars := Result.Dollars + 1;
      Result.Cents   := Cents_With_Overflow - 100;
   else
      Result.Cents   := Cents_With_Overflow;
   end if;

   return Result;
end "+";
1 JimRogers Oct 13 2020 at 05:33

Ein anderer Ansatz für dieses Problem besteht darin, die Dollar und Cent für jede Instanz von Price_Type in eine Gesamtzahl von Cent umzuwandeln. Addieren Sie einfach die zwei Cent-Werte und konvertieren Sie das Ergebnis zurück in Dollar und Cent.

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;

Ein Beispiel für die Ausführung dieses Programms erzeugt die folgende Ausgabe:

Enter the dollars for the price: 10
Enter the cents for the price: 41
Enter the dollars for the price: 0
Enter the cents for the price: 32
The sum of P1 and P2 is: 10.73

Ein weiteres Beispiel für die ordnungsgemäße Inkrementierung des Dollarbetrags, wenn die zwei Cent mehr als einen Dollar betragen, ist:

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