|
6.4 Case - Anweisung
Ähnlich einer If-Anweisung führt eine Case-Anweisung (case_statement
<BNF>) eine von mehreren alternativen Anweisungsfolgen aus.
Welche Anweisungsfolge zur Ausführung kommt, hängt von dem Wert
eines Ausdrucks ab, dem sogenannten Case-Selektor.
case AUSDRUCK is
when WERT_1 =>
-- Anweisungsfolge, wenn AUSDRUCK WERT_1 hat
when WERT_2 =>
-- Anweisungsfolge, wenn AUSDRUCK WERT_2 hat
when others =>
-- Anweisungsfolge, wenn AUSDRUCK anderen Wert hat
end case; |
Beispiel 1:
case Zeichen is
when 'a' .. 'z' | 'A' .. 'Z' =>
Zeichenart := BUCHSTABE;
when '0' .. '9' =>
Zeichenart := ZIFFER;
when '+' | '-' | '*' | '\' =>
Zeichenart := OPERATOR;
when others =>
Zeichenart := UNDEFINIERT;
raise Formelfehler;
end case; |
Für jeden potentiellen Wert des Case-Selektors muß es eine
Anweisungsfolge geben, die bei diesem Wert zur Ausführung kommt.
Im Beispiel ist "Zeichen" der Selektor.
Je nach Wert von "Zeichen" wird eine der möglichen Case-Alternativen
ausgeführt.
Falls keine Case-Alternative zutrifft, wird die Alternative "when others
=>" ausgewählt.
Beispiel 2:
case ZAEHLER_1 is
when 1 =>
VENTILE(ZAEHLER_1).OFFEN:=TRUE;
when 2 | 3 =>
VENTILE(ZAEHLER_1).OFFEN:=FALSE;
when 5..10 =>
VENTILE(ZAEHLER_1).OFFEN:=FALSE;
when others =>
VENTILE(ZAEHLER_1).OFFEN:=TRUE;
VENTILE(ZAEHLER_1).DRUCK:=1.0;
end case; |
Die Zuordnung von Anweisungsfolgen kann sowohl für einzelne Werte als auch
für Wertebereiche des Case-Selektors erfolgen.
Im Beispiel sind Anweisungen definiert, wenn der Wert des Case-Selektors ZAEHLER_1
1 ist (when 1).
2 oder 3 ist (when 2 | 3)
zwischen 5 und 10 liegt (when 5..10).
Eine weitere Anweisungsfolge berücksichtigt die others-Alternative (when
others). Das ist der Fall, wenn der Wert des Case-Selektors nicht in den genannten
Wertebereichen liegt.
Die Verwendung der Others-Alternative ist sinnvoll, wenn der Case-Selektor einen
großen Wertebereich besitzt, z. B. Integer.
Während bei einer If-Anweisung möglicherweise auch gar keine Anweisungsfolge
zur Ausführung kommt (falls kein else-Zweig existiert und die Bedingung für
den then-Zweig nicht erfüllt ist), wird bei einer Case-Anweisung immer genau
eine Anweisungsfolge ausgeführt. Es müssen also immer alle Möglichkeiten
aufgeführt werden.
Folgendes ist bei Case-Anweisungen zu beachten:
- Für jeden potentiellen Wert des Case-Selektors muß eine Anweisungsfolge
definiert sein, die bei diesem Wert zur Ausführung kommt. Damit dies erreicht
wird, müssen die Wertebereiche für die einzelnen alternativen Anweisungsfolgen
statisch sein und dürfen nicht erst während der Laufzeit festgelegt
werden. Eine Case-Alternative der Art "when A" wäre unzulässig,
da der Übersetzer nicht feststellen kann, ob der Case-Selektor während
der Laufzeit den Wert der Variablen "A" annehmen wird, wenn die anderen
Case-Alternativen nicht zutreffen. Zudem kann dies zu Mehrdeutigkeiten führen,
wenn eine Case-Alternative "when 2" lautet und A gerade diesen Wert
besitzt. Es ist dann unklar, ob die Anweisungsfolge für "A" oder
für "2" ausgeführt werden soll.
- Damit eindeutig ist, welche Anweisungsfolge für einen bestimmten Wert
des Case-Selektors auszuführen ist, müssen sich die einzelnen Case-Alternativen
wechselseitig ausschließen.
- Ein Ada-Übersetzer legt normalerweise eine Sprungtabelle für eine
Case-Anweisung an. Diese enthält einen Eintrag pro potentiellen Wert des
Case-Selektors und einen Eintrag für "others". Damit die Werte
für diese Tabelle aufgelistet werden können, müssen sie von einem
diskreten Typ sein - also von einem ganzzahligen oder einem Aufzählungstyp.
Der Typ des Case-Selektors kann also kein Gleitpunkttyp sein.
- Eine Case-Anweisung sollte nicht verwendet werden, wenn die einzelnen Wertebereiche
der Case-Alternativen sehr viele Elemente enthalten. Dann wird die vom Übersetzer
angelegte Sprungtabelle groß, so daß Laufzeitverluste zu befürchten
sind.
- Eine Case-Anweisung kann nicht verwendet werden, wenn die einzelnen Wertebereiche
dynamisch oder nicht diskret sind. In all diesen Fällen muß eine If-Anweisung
verwendet werden.
|