4. Typen und Datenstrukturen
 
zurück
4.3.2.2 Verbundtypen


Verbunde (record_definition <BNF>) sind sehr flexible und mächtige Hilfsmittel zum Aufbau komplexer Datenstrukturen. Zusammen mit Zugriffstypen bilden sie die Grundlage der Implementierung von rekursiven Datenstrukturen wie Listen, Bäumen, Graphen. Mit der Möglichkeit der Typerweiterung dienen sie auch der objektorientierten Spracherweiterung. Während Reihungstypen aus Komponenten des gleichen Typs bestehen, können Verbunde Komponenten unterschiedlicher Typen enthalten. Die Namen der Komponenten müssen alle unterschiedlich sein.

Es gibt verschiedene Arten von Verbunden:


Einfache Verbunde

Einfache Verbunde sind eingeschränkte Typen. Alle Objekte eines solchen Typs haben die gleiche Größe sowie die gleiche Art und Anzahl von Komponenten. Solche Verbundtypen ohne Diskriminanten dienen dazu, Objekte gleicher Struktur und Größe anzulegen.

Die Deklaration

type Bounded_String is record
   Length : Natural range 0 .. 1024;
   Data : String(1 .. 1024);
end record;


enthält die beiden Komponenten Length und Data.

Das folgende Fragment zeigt, wie man Objekte des Typs deklarieren und mit Aggregaten auf sie zuweisen kann und wie man auf die Komponenten mit Punktnotation zugreift:

   Text1:Bounded_String:=(1, "C" & (2 .. 256 => ' '));
   Text2: Bounded_String:=(Length => 8, Data => "Lady Ada" & (9 .. 256 => ' '));
   Text3: Bounded_String:=Bounded_String'(Length => 6, Data => "Ada 9X" & (7 .. 256 => ''));
begin
   Text1.Length := 3;
   Text1.Data(1 .. 3) := "C++";
   Text3:= Bounded_String'(Length => 5, Data => "Ada95" & (6 .. 256 => ' '));
   Text1 := Text3;
   put_line (Text1.Data);
   put_line (Text2.Data);
   put_line (Text3.Data);
   put_line (Text1.Data(1..Text1.Length));
   put_line (Text2.Data(1..Text2.Length));
   put_line (Text3.Data(1..Text3.Length));



Gemeinsame Deklaration von Komponenten

Enthalten Verbunde mehrere Komponenten gleichen Typs, so können sie in einer Deklaration gemeinsam angegeben werden (wie bei anderen Deklarationen auch), z. B. ist

type Complex is record
   Re, Im : Float;
end record;


eine Kurzfassung der folgenden äquivalenten Deklaration.

type Complex is record
   Re : Float;
   Im : Float;
end record;



Vorbesetzung von Komponenten

Bei der Typdeklaration können Komponenten vorbesetzt werden, z. B.:

type Bounded_String is record
   Length : natural RANGE 0 .. 1024 := 0;
   Data : String(1 .. 1024) := (others => ' ');
end record;

type Complex is record
   Re, Im : Float := 0.0;
end record;


Von der Möglichkeit der Vorbesetzung sollte Gebrauch gemacht werden, wann immer dies sinnvoll ist. Die Vorbesetzung hat zur Folge, daß sämtliche Objekte, die von solchen Verbundtypen deklariert werden, ohne explizite Vorbesetzung bei der Objektvereinbarung die Vorbesetzung der Typvereinbarung erhalten. Die Vereinbarungen

Z1 : Complex := (Re => 0.0, Im => 0.0);
Z2 : Complex;


führen dazu, daß sowohl Z1 als auch Z2 im Ursprung der komplexen Zahlenebene liegen.


Verbunde mit Diskriminanten

Verbunde mit Diskriminanten sind uneingeschränkte Typen, bei denen verschiedene Objekte unterschiedliche Größe (aufgrund unterschiedlicher Größe von Komponenten oder aufgrund unterschiedlicher Struktur andersartiger Komponenten) und Struktur haben können.

Von Verbundtypen mit Diskriminanten können also Objekte veränderlicher Größe und Struktur vereinbart werden. Zulässige Typen von Diskriminanten sind die diskreten Typen (ganzzahlige und Aufzählungstypen) sowie in Ada 95 auch Zugriffstypen.

Diskriminanten können zur Dimensionierung von Komponenten dienen, die von einem uneingeschränkten Feldtyp sind.

subtype dynamic_string_length is natural range 0 .. 1024;
type dynamic_string(length: dynamic_string_length := 0) is private;
function type_convert(of_string: in string) return dynamic_string;
-- weitere Type_Convert Funktionen
function "&" (left: in string; right: in dynamic_string) return dynamic_string;
-- weitere Verknüpfungsoperatoren
private
   type dynamic_string(length: dynamic_string_length := 0) is record
      data : string(1 .. length);
   end record;


Die Deklaration und Benutzung von Zeichenketten dieser Art geschieht wie folgt:

   Input : string(1 .. 128);
   length: natural := 0;
   Text : dynamic_string;
begin
   loop
      text_io.get_line(Input, length);
      exit when length = 0;
      Text := Input(1 .. length) & Text;
      -- Alle eingelesenen Zeichenketten werden verbunden
   end loop;
end;


Objekte vom Typ dynamic_string können ohne Angabe des Diskriminatenwertes deklariert werden, da die Diskriminante mit 0 vorbesetzt ist.

Diskriminanten können auch zum Aufbau einer varianten Struktur der Verbunde eingesetzt werden (variant_part <BNF>).Die Benutzbarkeit und damit der Nutzen varianter Verbunde ist ohne den gleichzeitigen Einsatz von Zugriffstypen stark eingeschränkt.

Verbunde mit Diskriminanten sind uneingeschränkte Typen wie die uneingeschränkten Reihungstypen.

Der Datenbank einer Personalabteilung könnte etwa folgender Datentyp zugrundeliegen:

type Gehalt is delta 0.01 digits 8; -- Auch beim Chef kein Ueberlauf

type Datum is record
   Jahr : positive range 1900 .. 2100;
   Monat : positive range 1 .. 12;
   Tag : positive range 1 .. 31;
end record;

Type Mitarbeiter_Geschlecht is (männlich, weiblich);

type Personen_daten(Geschlecht: Mitarbeiter_Geschlecht) is record
   Name : string(1 .. 100) := (others => ' ');
   Geburtsdatum : Datum;
   Personalnummer : positive range 1 .. 1_000_000; -- sollte reichen
   Jahres_Gehalt : Gehalt;
   case Geschlecht is
      when weiblich =>
         schwanger : boolean; -- ladies first
      when männlich =>
         gedient : boolean;
   end case;
end record;


Diese Typdeklaration enthält zunächst vier Komponenten, die bei beiden Varianten vorhanden sind. In der Case-Anweisung werden dann die unterschiedlichen Variablen vereinbart.


 
zurück
 Index   Ada Tour - Dokumentation  
© 2003 Förderverein Ada Deutschland e.V.