Eigene Typen und Subtypen
Das mächtigste Feature von Ada: Typen beschreiben Wertebereiche, die der Compiler und die Laufzeit prüfen:
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Prozent is range 0 .. 100;
type Temperatur is digits 5 range -273.15 .. 1000.0;
type Farbe is (Rot, Gruen, Blau);
subtype Kleine_Zahl is Integer range 1 .. 10;
type Wochentag is (Mo, Di, Mi, Don, Fr, Sa, So);
subtype Werktag is Wochentag range Mo .. Fr;
P : Prozent := 75;
T : Temperatur := 21.5;
F : Farbe := Gruen;
K : Kleine_Zahl := 5;
W : Wochentag := Mi;
begin
Put_Line (Prozent'Image (P));
Put_Line (Farbe'Image (F) & Integer'Image (Farbe'Pos (F)));
Put_Line (Farbe'Image (Farbe'Succ (F)));
Put_Line (Boolean'Image (W in Werktag));
Put_Line (Boolean'Image (Wochentag'Succ (W) = Don));
Put_Line (Integer'Image (Kleine_Zahl'First) & Integer'Image (Kleine_Zahl'Last));
for Tag in Wochentag loop
Put (Wochentag'Image (Tag) & " ");
end loop;
New_Line;
Put_Line (Boolean'Image (T > 20.0));
K := K + 5;
Put_Line (Integer'Image (K));
K := K + 1;
Put_Line ("nicht erreicht");
exception
when Constraint_Error =>
Put_Line ("Wertebereich verletzt");
end Main;Ausgabe
75 GRUEN 1 BLAU TRUE TRUE 1 10 MO DI MI DON FR SA SO TRUE 10 Wertebereich verletzt
Außerhalb des Wertebereichs löst Ada zur Laufzeit Constraint_Error aus – ein Pufferüberlauf oder ungültiger Wert fällt sofort auf.
Arrays
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Feld is array (1 .. 5) of Integer;
type Matrix is array (1 .. 2, 1 .. 3) of Integer;
type Tag_Zahlen is array (Character range 'a' .. 'e') of Natural;
type Offenes_Feld is array (Positive range <>) of Integer;
F : Feld := (1, 4, 9, 16, 25);
M : Matrix := (others => (others => 0));
Z : Tag_Zahlen := (others => 0);
function Summe (A : Offenes_Feld) return Integer is
S : Integer := 0;
begin
for X of A loop
S := S + X;
end loop;
return S;
end Summe;
begin
F (2) := 40;
Put_Line (Integer'Image (F (2)) & Integer'Image (F'Length) & Integer'Image (F'First) & Integer'Image (F'Last));
M (2, 3) := 7;
Put_Line (Integer'Image (M (2, 3)));
Z ('c') := 3;
Put_Line (Integer'Image (Z ('c')));
Put_Line (Integer'Image (Summe (Offenes_Feld (F))));
Put_Line (Integer'Image (Summe (Offenes_Feld (F (2 .. 3)))));
for I in F'Range loop
Put (Integer'Image (F (I)));
end loop;
New_Line;
declare
Index : Integer := 6;
begin
F (Index) := 1;
exception
when Constraint_Error => Put_Line ("Indexfehler abgefangen");
end;
end Main;Ausgabe
40 5 1 5 7 3 91 49 1 40 9 16 25 Indexfehler abgefangen
Der letzte Zugriff mit Index 6 liegt außerhalb von 1 .. 5. Statt eines stillen Speicherfehlers wie in C löst Ada zur Laufzeit Constraint_Error aus, den man abfangen kann.
Strings
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Characters.Handling; use Ada.Characters.Handling;
procedure Main is
S : String := "Hallo Ada";
U : Unbounded_String := To_Unbounded_String ("Anfang");
begin
Put_Line (Integer'Image (S'Length));
Put_Line (S (1 .. 5));
Put_Line (To_Upper (S));
Put_Line (To_Lower (S));
Put_Line (Integer'Image (Index (S, "Ada")));
Put_Line (Trim (" x ", Ada.Strings.Both) & "|");
Put_Line (5 * "ab");
Append (U, " und Ende");
Put_Line (To_String (U));
Put_Line (Integer'Image (Length (U)));
Put_Line (Integer'Image (Integer'Value ("42") + 1));
Put_Line (Boolean'Image (Is_Digit ('7')) & Boolean'Image (Is_Letter ('7')));
Put_Line ((1 .. 3 => '*'));
Put_Line (S & "!" & '?');
Put_Line (Boolean'Image (S < "Hallo Zeta"));
end Main;Ausgabe
9 Hallo HALLO ADA hallo ada 7 x| ababababab Anfang und Ende 15 43 TRUEFALSE *** Hallo Ada!? TRUE
Records und Varianten
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Person is record
Name : String (1 .. 3);
Alter : Natural;
end record;
type Form_Art is (Kreis, Rechteck);
type Form (Art : Form_Art) is record
case Art is
when Kreis => Radius : Float;
when Rechteck => Breite, Hoehe : Float;
end case;
end record;
P : Person := (Name => "Mia", Alter => 17);
K : Form := (Art => Kreis, Radius => 2.0);
R : Form := (Art => Rechteck, Breite => 3.0, Hoehe => 4.0);
function Flaeche (F : Form) return Float is
begin
case F.Art is
when Kreis => return 3.14159 * F.Radius * F.Radius;
when Rechteck => return F.Breite * F.Hoehe;
end case;
end Flaeche;
begin
Put_Line (P.Name & Natural'Image (P.Alter));
P.Alter := P.Alter + 1;
Put_Line (Natural'Image (P.Alter));
Put_Line (Float'Image (Flaeche (K)));
Put_Line (Float'Image (Flaeche (R)));
end Main;Ausgabe
Mia 17 18 1.25664E+01 1.20000E+01
Merke
- Eigene Typen mit Wertebereich (
range) und Subtypen werden zur Laufzeit geprüft - Aufzählungen (
(Rot, Gruen, Blau)) haben Attribute wie'Succ,'Pos,'Image - Arrays haben beliebige Indexbereiche;
'First,'Last,'Lengthund'Rangebeschreiben sie - Records können Varianten (
case) enthalten; Strings sind Arrays vonCharacter
Aufgabe
Definiere einen Typ Note is range 1 .. 6 und teste, was bei Note'Succ (6) passiert.