Pascal-Tutorial (Vorwort, Installation, Kapitel 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12)

Bedingte Anweisungen

In diesem Kapitel:

5.1. IF-Anweisung

Sie haben bereits gelernt, den Benutzer Eingaben machen zu lassen, doch auswerten konnten Sie diese bisher noch nicht, da Ihnen dazu noch die nötigen Kenntnisse fehlen. Um Eingaben auswerten zu können, benötigt man sog. Kontrollanweisungen (Kontrollstrukturen). Mit Kontrollstrukturen lässt sich der Programmfluss (Programmablauf) steuern. Sie können bestimmte Programmierzeilen nur dann ausführen lassen, wenn eine bestimmte Bedingung eintritt bzw. erfüllt ist (IF- oder CASE-Anweisung, in diesem Kapitel und 5.2). Sie können aber auch Code so lange ausführen lassen, solange eine Bedingung erfüllt ist, bzw. bis eine Bedingung erfüllt wird. Letzteres (sog. Schleifen) wird in Kapitel 6 behandelt.

Die IF-Anweisung führt einen Anweisungsblock (dieser besteht aus einzelnen Programmierzeilen) nur unter einer bestimmten Bedingung aus. Nehmen wir einmal an, es soll ein Anweisungsblock nur dann ausgeführt werden, wenn zwei eingegebene Zahlen gleich sind. Also gibt der Benutzer zwei Zahlen ein, ich nehme einmal 2 (für die erste Zahl) und 2 (für die zweite Zahl) an. Danach zeigt das Programm Zahlen gleich auf dem Bildschirm an. Im Anweisungsblock steht dazu die Zeile Write ('Zahlen gleich');, um diese Aktion auszuführen.

Der Anweisungsblock selbst beginnt mit BEGIN und endet mit END; (hier kein Punkt am Ende, es ist schließlich nicht das Ende des Programms!). Fehlt also noch die Anweisung, die die bedingte Ausführung definiert. Ist die Bedingung übrigens nicht erfüllt, wird der Anweisungsblock auch nicht ausgeführt. Er wird übersprungen und die Zeilen, die danach folgen, werden ausgeführt. Es kann aber zusätzlich ein Anweisungsblock angegeben werden, der nur dann ausgeführt wird, wenn die Bedingung NICHT erfüllt wird (ELSE-Anweisungsblock).

Was nach dem IF- bzw. ELSE-Anweisungsblock folgt, wird im Anschluss ganz normal ausgeführt, der normale Programmablauf geht weiter.

Aber nun Schritt für Schritt. Die IF-Anweisung hat im einfachsten Fall folgende Syntax (Grammatik):

IF Bedingung THEN Anweisung;

Kleine Info am Rande: Pascal hat hier sehr sprechende Schlüsselwörter (IF, THEN). Schlüsselwörter sind reservierte Bezeichner, die Sie nicht selbst - z.B. für Variablen - verwenden dürfen. Da Pascal als leicht erlernbare Sprache konzipiert wurde, hat man hier sprechende und logische Namen verwendet. Aus IF und THEN geht bereits hervor, was passiert: WENN eine Bedingung erfüllt ist, DANN tue ...

Nach THEN folgt dann die Anweisung (oder der Anweisungsblock mit einer/mehreren Anweisungen; siehe unten), die, wenn die Bedingung erfüllt ist, ausgeführt wird. Ist sie nicht erfüllt, passiert nichts, und die nächsten Anweisungen werden ausgeführt.

Die Bedingung muss ein boolescher Ausdruck sein. Daher, die Bedingung darf als Ergebnis nur wahr oder falsch sein. Nun lernen Sie einige weitere Operatoren kennen, nämlich Logische Operatoren. In den weiteren Beispielen gehe ich wieder davon aus, dass die Variable a vom Typ Integer ist.

IF a = 2 THEN WriteLn ('Die Variable a hat den Wert 2.');

Der = - Operator (Gleichheitsoperator) überprüft in dem Fall, ob die Variable den Wert 2 hat. Hat sie diesen Wert, wird die WriteLn-Anweisung ausgeführt, die nach THEN steht. Bei dieser IF-Variante wird nur eine Programmierzeile nach THEN akzeptiert. Mit dem Semikolon endet die IF-Anweisung. Schauen Sie sich dazu einmal das folgende Beispiel an:

PROGRAM IF_Test;
USES Crt;
BEGIN
  IF 1 = 2 THEN
    WriteLn ('1 ist offenbar gleich 2 ... faszinierend');
    WriteLn ('Diese Zeile wird ausgeführt, egal ob die Bedingung zutrifft oder nicht.');
  ReadKey;
END.

Führen Sie das Beispiel aus und testen Sie was passiert. Es wird eine Zeile Text auf dem Bildschirm ausgegeben: Diese Zeile wird ausgeführt, egal ob die Bedingung zutrifft oder nicht.. Doch wie kam es dazu? Die Bedingung 1 = 2 ist natürlich falsch, kann nie wahr werden (weil beides Konstanten sind; was Sie als Zahl, Text oder sonstwie "fix" in den Quellcode schreiben, gilt auch als Konstante), und ist daher nicht erfüllt (weil falsch bzw. nicht wahr).

Die zweite WriteLn-Anweisung folgt nach der IF-Anweisung, also nach dem Semikolon der auf THEN folgenden Anweisung. Ich habe absichtlich die Anweisungen so eingerückt, dass es leicht verwirrend wirkt. Einrückungen (Leerzeichen/Abstände) können auch verwirren. Übersichtlicher ist natürlich:

PROGRAM IF_Test;
USES Crt;
BEGIN
  IF 1 = 2 THEN
    WriteLn ('1 ist offenbar gleich 2 ... faszinierend');
 
  WriteLn ('Diese Zeile wird ausgeführt, egal ob die Bedingung zutrifft oder nicht.');
  ReadKey;
END.

Weitere Beispiele zur einfachsten Form der IF-Anweisung:

IF a <> 2 THEN
  WriteLn ('Der Wert der Variable ist kleiner oder größer als 2, jedoch NICHT 2!');

Hier wurde der Ungleich-Operator <> verwendet. Mit diesem wird im Bsp. überprüft, ob der Wert der Variable a einen anderen Wert als 2 hat. Ist der Wert gleich 2, wäre die Bedingung NICHT erfüllt.

IF a < 2 THEN WriteLn ('Der Wert der Variable a ist kleiner als 2!');

IF a > 2 THEN WriteLn ('Der Wert der Variable ist größer als 2!');

Im ersten Beispiel ist die Bedingung dann erfüllt, wenn der Wert von a kleiner als 2 ist. Ist der Wert von a genau gleich 2, wäre die Bedingung nicht erfüllt! Umgekehrt ist es beim zweiten Beispiel. Hier ist die Bedingung dann erfüllt, wenn der Wert von a größer als 2 ist. Bei a gleich 2 ist die Bedingung auch hier nicht erfüllt.

Für die Fälle Kleiner-Gleich und Größer-Gleich gibt es die Operatoren <= und >=:

IF a <= 2 THEN WriteLn ('Die Variable a kann 2 oder einen kleineren Wert haben.');

IF a >= 2 THEN WriteLn ('Die Variable a kann 2 oder einen größeren Wert haben.');

Etwas komplizierter wird es, wenn man mehrere Bedingungen verknüft. Zum Beispiel kann man so bestimmen, dass der Wert der Variable a größer als 5 UND aber kleiner als 10 sein muss, also 6, 7, 8 oder 9 sein darf. Dies erreichen wir durch Verwendung des AND-Operators. Weitere Operatoren zum Verknüpfen von Bedingungen sind OR, XOR und NOT. Es folgen wieder einige Beispiele:

IF (a > 5) AND (a < 10) THEN 
  WriteLn ('Der Wert der Variable a muss größer als 5 und kleiner als 10 sein.'); 

Letzte Zeile passt zum eben genannten Beispiel. Hier ist die Bedingung als Ganzes (und darauf kommt's an!) nur dann erfüllt, wenn zwei Bedingungen erfüllt sind. Die erste Bedingung ist a > 5. Die zweite Bedingung ist a < 10. Wichtig ist, dass beide Bedingungen in Klammer stehen müssen. Der Grund dafür liegt in den Prioritäten der einzelnen Operatoren. Die Klammer-Operatoren ( und ) haben eine höhere Priorität als AND (sowie OR, XOR und NOT). Lässt man die Klammern weg, würde der Compiler annehmen, dass 5 AND a ein zusammen gehörender Ausdruck ist, da diese beiden Operanden neben AND stehen. Wenig sinnvoll also.

Schauen wir uns noch einige weitere Beispiele zu diesen Operatoren an.

IF (a = 5) OR (b = 10) THEN
  WriteLn ('Entweder hat a den Wert 5, oder b den Wert 10. Oder beides.');

Sie müssen immer die Bedingung als Ganzes betrachten. Das ist kurz gesagt alles, was zwischen IF und THEN steht. Was wir vorhin gemacht haben und auch weiterhin machen, ist, die Bedingung zur einfacheren Anschauung quasi in mehrere Teile zu unterteilen. Auf dieses Beispiel angewandt sind das die Ausdrücke a = 5 und b = 10. Verknüpft werden beide mit dem OR-Operator (ODER-Verknüpfung). Das bedeutet, dass nur einer der beiden Ausdrücke wahr sein muss, damit der Anweisungsblock ausgeführt wird. Es können aber auch beide wahr sein. Was jedoch nicht der Fall sein darf, ist, dass gar keiner wahr ist.

IF (a = 5) XOR (b = 10) THEN
  WriteLn ('Entweder hat a den Wert 5, oder b den Wert 10.');

    (* Anmerkung: Beides darf nicht sein! *)

XOR ist ein logisches ENTWEDER-ODER. Es darf einer von beiden Teilen wahr sein, nicht jedoch beide oder gar keiner.

IF NOT (a = 5) THEN WriteLn ('a hat nicht den Wert 5.');

Die Bedingung als Ganzes ist erfüllt, wenn der Ausdruck, der in der Klammer nach NOT steht, NICHT erfüllt ist! Es geht noch komplizierter. Das nächste Beispiel sollen demonstrieren, wie sich mehrere Bedingungen verknüpfen lassen:

IF ((a = 5) XOR (b = 50)) AND (c <> 10) THEN
  WriteLn ('a ist 5 oder b ist 50 sowie c hat einen Wert ungleich 10.'); 

Wichtig sind hier die korrekt gesetzten Klammern. Um diese Anweisung leichter verstehen zu können, ist wichtig zu erkennen, was miteinander verknüpft ist. Einerseits ist dies die ganze Bedingung ((a = 5) XOR (b = 50)) AND (c <> 10) sowie in der ersten Klammer noch (a = 5) XOR (b = 50). Damit die gesamte Bedingung erfüllt ist, muss zunächst einmal (a = 5) XOR (b = 50) erfüllt sein. Ist diese Bedingung erfüllt, überprüft der Compiler noch die zweite Klammer c <> 10. Da beides mit AND verknüpft ist, muss auch beides erfüllt sein. Das bedeutet nun jetzt, dass entweder a den Wert 5 haben muss oder b den Wert 50 (nicht beides gleichzeitig). Weiters darf c nicht den Wert 10 haben. Ist all dies gegeben, wird der Anweisungsblock ausgeführt.

Anweisungsblock ist hier übertrieben (und eigentlich falsch), wenn man - wie ich vorhin - nur eine Programmierzeile damit meint. Anweisungsblöcke beginnen immer mit BEGIN und enden mit END. Dazwischen stehen die Programmierzeilen (darf auch nur eine sein). Nach dem END folgt allerdings ein normales Semikolon und KEIN Punkt. Das sieht dann so aus:

IF Bedingung THEN
BEGIN
  Anweisung 1
  Anweisung 2
  Anweisung 3
...
END;

Ein Beispiel:

PROGRAM IF_Anweisung;
USES Crt;
 
VAR Eingabe: Integer;
 
BEGIN
  ClrScr;
  Write ('Geben Sie eine Zahl ein: ');
  ReadLn (Eingabe);
 
  IF eingabe < 100 THEN
  BEGIN
    WriteLn ('Es wurde vorhin ein Wert <100 eingegeben.');
    WriteLn ('Drücken Sie eine Taste, um das Programm zu beenden ...');
    ReadKey;
  END;
 
END.

Dieses Beispiel bedarf meiner Meinung nach keiner näheren Erläuterung. Sie wissen bereits, dass der Anweisungsblock der IF-Anweisung immer nur dann ausgeführt wird, wenn die Bedingung erfüllt ist. Wird die Bedingung nicht erfüllt, wird dieser bekanntlich nicht ausgeführt und die Programmausführung nach der IF-Anweisung fortgesetzt.

Die nachfolgenden Zeilen werden sowieso ausgeführt, ob die Bedingung erfüllt wurde oder nicht. Pascal bietet uns allerdings auch die Möglichkeit, einen Anweisungsblock festzulegen, der nur dann ausgeführt wird, wenn die Bedingung NICHT erfüllt ist! Die Syntax dieser Form der IF-Anweisung (nun eigentlich IF-ELSE-Anweisung) sieht folgendermaßen aus:

IF Bedingung THEN Anweisung     (* hier darf KEIN Semikolon stehen! *)
ELSE Ersatzanweisung;

Wenn Sie einen ELSE-Block verwenden, darf nach dem IF-Anweisungsblock (bzw. der einzigen Anweisung) KEIN Semikolon folgen. Vermeiden Sie diesen häufig gemachten Fehler.

Die Syntax mit Anweisungsblöcken:

IF Bedingung THEN
BEGIN
  Anweisung 1
  Anweisung 2
...
END     (* hier kein Semikolon! *)
ELSE
BEGIN
  Ersatzanweisung 1
  Ersatzanweisung 2
...
END;

Es folgt wieder ein vollständiges, ausführbares Beispiel:

PROGRAM IF_ELSE_Anweisung;
USES Crt;
 
VAR Eingabe: Integer;
 
BEGIN
  ClrScr;
  Write ('Geben Sie eine Zahl ein: ');
  ReadLn (Eingabe);
 
  IF Eingabe < 100 THEN
  BEGIN
    WriteLn ('Die Bedingung wurde erfüllt.');
    WriteLn ('Sie haben einen Zahl eingegeben, die kleiner als 100 ist.');
  END
  ELSE
  BEGIN
    WriteLn ('Die Bedingung wurde nicht erfüllt.');
    WriteLn ('Sie haben einen Zahl eingegeben, die größer oder gleich 100 ist.');
  END;
 
  WriteLn ('Drücken Sie eine Taste, um das Programm zu beenden ...');
  ReadKey;
END.

Umständlich wird die Verwendung der IF-Anweisung allerdings dann, wenn Sie mehrere Überprüfungen vornehmen möchten. Nehmen wir einmal das vorige Beispiel her. Der Benutzer soll eine Zahl eingeben. Nun wollen wir bewerkstelligen, dass je nach Eingabe vom Benutzer ein anderer Text angezeigt wird. Gibt der Benutzer einen Wert von 1-20 ein, soll ein Text angezeigt werden, der den Benutzer darauf hinweist, dass seine Eingabe in diesem Bereich liegt. Ähnliches soll mit 21-40, 41-60, 61-80 sowie 81-100 geschehen. Das bedeutet, wir müssen 5 Überprüfungen durchführen. Dies lässt sich natürlich mit IF-Anweisungen lösen, ist jedoch ziemlich viel Tipparbeit. Vor allem ziemlich viel unnötige Tipparbeit. Wie das einfacher geht, werden Sie in Abschnitt 5.2 (CASE-Anweisung) sehen.

PROGRAM Verzweigungen_IF;
USES Crt;
 
VAR Eingabe: Integer;
 
BEGIN
  ClrScr;
  Write ('Geben Sie eine Zahl ein: ');
  ReadLn (Eingabe);
 
  IF (Eingabe > 0) AND (Eingabe < 21) THEN
    WriteLn ('Ihre Eingabe liegt im Bereich von 1 bis 20.');
  IF (Eingabe > 20) AND (Eingabe < 41) THEN
    WriteLn ('Ihre Eingabe liegt im Bereich von 21 bis 40.');
  IF (Eingabe > 40) AND (Eingabe < 61) THEN
    WriteLn ('Ihre Eingabe liegt im Bereich von 41 bis 60.');
  IF (Eingabe > 60) AND (Eingabe < 81) THEN
    WriteLn ('Ihre Eingabe liegt im Bereich von 61 bis 80.');
  IF (Eingabe > 80) AND (Eingabe < 101) THEN
    WriteLn ('Ihre Eingabe liegt im Bereich von 81 bis 100.');
 
  WriteLn ('Drücken Sie eine Taste, um das Programm zu beenden ...');
  ReadKey;
END. 

5.2. CASE-Anweisung

Bei Mehrfachüberprüfung wie im letzten Beispiel lohnt es sich, statt einer IF- eine CASE-Anweisung einzusetzen. Diese hat folgende Syntax:

CASE Variable OF
  Wert 1: Anweisung 1;
  Wert 2: Anweisung 2;
  ...
END;

Die CASE-Anweisung überprüft die angegebene Variable auf deren Wert. Je nachdem, welchen Wert die Variable hat, wird ein anderer Anweisungsblock ausgeführt. Am einfachsten kann man dies anhand eines Beispiels nachvollziehen:

PROGRAM CASE_Anweisung;
USES Crt;
 
VAR Eingabe: Integer;
 
BEGIN
  ClrScr;
  Write ('Geben Sie eine Zahl von 1 bis 5 ein: ');
  ReadLn (Eingabe);
 
  CASE Eingabe OF
    1: WriteLn ('Sie haben Eins eingegeben.');
    2: WriteLn ('Sie haben Zwei eingegeben.');
    3: WriteLn ('Sie haben Drei eingegeben.');
    4: WriteLn ('Sie haben Vier eingegeben.');
    5: WriteLn ('Sie haben Fünf eingegeben.');
  END;
 
  WriteLn ('Drücken Sie eine Taste, um das Programm zu beenden ...');
  ReadKey;
END.

Ist die Eingabe nun z.B. 2, wird nur der Text Sie haben Zwei eingegeben. angezeigt. Wäre die Eingabe allerdings z.B. 7, würde nichts angezeigt werden. Für 7 wurde kein Fall definiert. Es lässt sich auch feststellen, ob die Eingabe in einem Wertebereich (von ... bis; nicht ein Einzelwert wie bisher) liegt:

PROGRAM CASE_Anweisung_Beispiel2;
USES Crt;
 
VAR Eingabe: Integer;
 
BEGIN
  ClrScr;
  Write ('Geben Sie eine Zahl ein: ');
  ReadLn (Eingabe);
 
  CASE Eingabe OF
     1..20: WriteLn ('Ihre Eingabe liegt im Bereich von 1 bis 20.');
    21..40: WriteLn ('Ihre Eingabe liegt im Bereich von 21 bis 40.');
    41..60: WriteLn ('Ihre Eingabe liegt im Bereich von 41 bis 60.');
    61..80: WriteLn ('Ihre Eingabe liegt im Bereich von 61 bis 80.');
    81..100: WriteLn ('Ihre Eingabe liegt im Bereich von 81 bis 100.');
  END;
 
  WriteLn ('Drücken Sie eine Taste, um das Programm zu beenden ...');
  ReadKey;
END.

Das letzte Beispiel ist das verbesserte Beispiel, bei dem zuvor IF-Anweisungen verwendet wurden. Durch die Verwendung der CASE-Anweisung haben wir uns hier nicht nur Tipparbeit erspart, sondern auch die Übersichtlichkeit gesteigert.

Es sind auch mehrere Einzelangaben in einem Zweig erlaubt:

CASE Variable OF
  1,2,5: WriteLn ('Bereich 1, 2 und 5');
  7,10..20: WriteLn ('Bereich 7 sowie 10 bis 20');
END;

CASE ist aber kein Ersatz für jegliche IF-Anweisung! "Komplizierte" Ausdrücke wie oben sind nämlich nicht möglich. Eine Möglichkeit der CASE-Anweisung fehlt noch: Die Möglichkeit, einen ELSE-Zweig zu definieren. Dieser wird dann ausgeführt, wenn keiner der anderen Fälle zutrifft. Das nächste Beispiel zeigt außerdem, dass statt einzelnen Anweisungen auch Anweisungsblöcke funktionieren:

PROGRAM CASE_Anweisung_Beispiel3;
USES Crt;
 
VAR Eingabe: Integer;
 
BEGIN
  ClrScr;
  Write ('Geben Sie eine Zahl ein: ');
  ReadLn (Eingabe);
 
  CASE Eingabe OF
     1..20: 
       BEGIN
         Write ('Ihre Eingabe liegt im Bereich von 1 bis 20.');
         WriteLn;     (* Zeilenumbruch; hier ist dem Autor nichts Besseres eingefallen *)
       END;
    21..40: WriteLn ('Ihre Eingabe liegt im Bereich von 21 bis 40.');
    41..60: WriteLn ('Ihre Eingabe liegt im Bereich von 41 bis 60.');
    61..80: WriteLn ('Ihre Eingabe liegt im Bereich von 61 bis 80.');
    81..100: WriteLn ('Ihre Eingabe liegt im Bereich von 81 bis 100.');
    ELSE    (* hier darf kein Doppelpunkt stehen, auch nicht bei nur einer Anweisung! *)
      BEGIN
        WriteLn ('Sie haben etwas anderes als 1-100 eingegeben.');
        WriteLn ('Bitte nur Zahlen von 1 bis 100 eingeben.');
      END;
  END;
 
  WriteLn ('Drücken Sie eine Taste, um das Programm zu beenden ...');
  ReadKey;
END.
Vorheriges Kapitel Nächstes Kapitel