|
6.2 Wertzuweisungen
Eine Wertzuweisung(assignment_statement
<BNF>)ordnet einem variablen Objekt einen neuen Wert zu. Der Bezeichner
des Objektes und sein neuer Wert werden durch das Symbol := voneinander
getrennt. Der neue Wert, den das Objekt erhält, wird durch einen Ausdruck
repräsentiert.
Der Typ des variablen Objektes muß mit dem Typ seines neuen Wertes
übereinstimmen. Eine Ausnahme ist gegeben, wenn der Typ des Objektes
klassenweit ist. Dann muß der Typ des neuen Wertes derselben Klasse
oder einer seiner Unterklassen angehören wie der klassenweite Typ
des Objektes. Er muß aber nicht mit dem Typ des Objektes identisch
sein.
Wird bei der Wertzuweisung der Wertebereich der Typvereinbarung verletzt, so
wird zur Programmlaufzeit die Ausnahme "Constraint_Error" ausgelöst.
with Text_IO; use Text_IO;
procedure Irgendwelche_Wertzuweisungen is
type My_Float is digits 8;
Spannung_1, Spannung_2 : My_Float;
type Matrix is array(Integer range <>, Integer
range <>) of My_Float;
Matrix_1, Matrix_2 : Matrix(1..5, 1..5);
type Personal is record
Name : String(1..25);
Alter : Integer;
end record;
type Personalliste is array(1..100) of Personal;
Meine_Personalliste : Personalliste;
Mitarbeiternummer : Integer range 1..100 := 1;
Mitarbeiter : Personal;
type Dynamische_Personalliste;
type Personalzeiger is access Dynamische_Personalliste;
type Dynamische_Personalliste is record
Name_Mitarbeiter : String(1..25);
Alter : Integer;
Nächster_Mitarbeiter : Personalzeiger;
end record;
Listenelement : Personalzeiger := new Dynamische_Personalliste;
begin
-- das variable Objekt wird durch eine einfache
Variable repräsentiert:
Spannung_2 := 12.0;
Spannung_1 := 24.0 + Spannung_2;
Put_Line ("Spannung_1: " & My_Float'Image
(Spannung_1));
-- das variable Objekt wird durch eine indizierte
Variable
-- repräsentiert, die den Zugriff auf die Komponenten
einer
-- Reihung erlaubt:
Matrix_2(2, 2) := 2.0 * 2.0;
Put_Line ("Matrix_2(2, 2): " & My_Float'Image
(Matrix_2(2, 2)));
-- das variable Objekt wird wieder durch eine einfache
Variable repräsentiert:
Matrix_1 := Matrix_2;
Put_Line ("Matrix_1(2, 2): " & My_Float'Image
(Matrix_1(2, 2)));
New_Line;
-- das variable Objekt ist ein Ausschnitt aus einer
Reihung:
Meine_Personalliste(Mitarbeiternummer..Mitarbeiternummer
+ 2) :=
((Name
=> " Mister X", Alter => 34),
(Name
=> " Nobody", Alter => 35),
(Name
=> " Das Phantom in der Oper", Alter => 36));
Put ("Mitarbeiter " & Integer'Image
(Mitarbeiternummer + 0) &
":"
& Meine_Personalliste(Mitarbeiternummer + 0).Name);
Put_Line (" Alter:" & Integer'Image(Meine_Personalliste(Mitarbeiternummer+0).Alter));
Put ("Mitarbeiter " & Integer'Image
(Mitarbeiternummer + 1) &
":" & Meine_Personalliste(Mitarbeiternummer + 1).Name);
Put_Line (" Alter:" & Integer'Image(Meine_Personalliste(Mitarbeiternummer
+ 1).Alter));
Put ("Mitarbeiter " & Integer'Image
(Mitarbeiternummer + 2) &
":" & Meine_Personalliste(Mitarbeiternummer + 2).Name);
Put_Line (" Alter:" & Integer'Image(Meine_Personalliste(Mitarbeiternummer
+ 2).Alter));
New_Line;
-- das variable Objekt wird durch eine Teilvariable
repräsentiert,
-- die den Zugriff auf eine Komponente eines Verbundes
erlaubt:
Mitarbeiter.Name := "SOUNDSO ";
Put_Line ("Noch ein Mitarbeiter: " &
Mitarbeiter.Name);
Meine_Personalliste(Mitarbeiternummer + 3).Name(1..7)
:= "SOUNDSO";
Put_Line ("Mitarbeiter " & Integer'Image
(Mitarbeiternummer + 3) &
":" & Meine_Personalliste(Mitarbeiternummer + 3).Name(1..7));
-- das variable Objekt wird indirekt über seine
Adresse referenziert (explizite Dereferenzierung):
Listenelement.all := (Name_Mitarbeiter =>
" SOUNDSO",
Alter
=>
34,
Nächster_Mitarbeiter
=> new Dynamische_Personalliste);
Put ("Und noch ein Mitarbeiter: " &
Listenelement.Name_Mitarbeiter);
Put_Line (" Alter:" & Integer'Image
(Listenelement.Alter));
New_Line;
declare
-- Beispiele zu erweiterbaren
Typen:
-- Basistyp, als "tagged"
gekennzeichnet:
type Mensch is tagged record
Name: String(1..25);
end record;
-- abgeleiteter Typ mit Erweiterung:
type Mann is new Mensch with record
Bärtig:
Boolean;
end record;
-- abgeleiteter Typ ohne Erweiterung:
type Frau is new Mensch with null
record;
P : Mensch;
M : Mann;
F : Frau;
begin
-- Zuweisungen an Objekte erweiterbarer
Typen:
P := (Name => " Lord Byron");
M := (Name => " Lord Byron",
Bärtig => True);
F := (Name => " Lady Ada");
Put_Line (P.Name & "
war ein Mensch!");
if M.Bärtig = True then
Put_Line ("Dieser
Mensch war ein Mann mit Bart: " & M.Name);
end if;
Put_Line ("Das war seine
Schwester: " & F.Name);
New_Line;
end;
end Irgendwelche_Wertzuweisungen; |
Beachte:
Ist eine Variable von einem klassenweiten Typ wie z. B. "PERSONENclass",
muß der Übersetzer wissen, wieviel Speicherplatz er für sie reservieren
muß. Die Variable muß daher zur Übersetzungszeit initialisiert
werden. Der Klassentyp, mit dem sie initialisiert wurde, darf während der
Laufzeit nicht verändert werden. Andernfalls könnte dies zu Speicherproblemen
führen, da für die Darstellung unterschiedlicher Klassentypen unterschiedlich
viel Speicher benötigt wird.
Soll der Klassentyp während der Laufzeit verändert werden,
muß die Variable auf Objekte des klassenweiten Typs verweisen, der Typ muß
z. B. "access PERSONENclass" sein. Das führt nicht zu Speicherproblemen,
da der Übersetzer weiß, wieviel Speicherplatz er für einen Adreß-verweis
reservieren muß.
|