EMZETT.
Login

Kurz: Das mächtigste Feature von Ada: Typen beschreiben Wertebereiche, die der Compiler und die Laufzeit prüfen:

Teil des Kurses Ada

Kapitel 3 von 8 im Kurs Ada. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

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, 'Length und 'Range beschreiben sie
  • Records können Varianten (case) enthalten; Strings sind Arrays von Character

Übungsaufgabe

Definiere einen Typ Note is range 1 .. 6 und teste, was bei Note'Succ (6) passiert.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Kontrollfluss, Prozeduren und Funktionen

Weiter: Pakete, Generics und Objekte

Alle Kapitel: Ada im Überblick