So definieren Sie "+" für einen Datensatztyp
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
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 "+";
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