2 Entscheidungen

Zum vorigen Kapitel Zum Inhaltsverzeichnis Zum nächsten Kapitel


Im ersten Kapitel haben wir gelernt, dass es nur 3 mögliche logische Grundstrukturen in einem Algorithmus gibt, nämlich Sequenz, Entscheidung und Schleife. Bisher haben wir nur Sequenzen benutzt; nun wollen wir uns an die Entscheidungen wagen. Zur Erinnerung sei hier nochmals das Struktogramm der Entscheidung abgebildet:


In Delphi ist die Entscheidung in der Form der IF....THEN...ELSE- Anweisung implementiert:
        IF Bedingung THEN
          Anweisung_1
        ELSE
          Anweisung_2;
Dabei wird die Anweisung_1 ausgeführt, wenn die Bedingung erfüllt ist; ist die Bedingung nicht erfüllt, wird stattdessen Anweisung_2 ausgeführt.
In Java ist die Entscheidung in der Form der if()...else....- Anweisung implementiert:
        if ( Bedingung ) {
          Anweisung_1
        } else {
          Anweisung_2
        };
Dabei wird die Anweisung_1 ausgeführt, wenn die Bedingung erfüllt ist; ist die Bedingung nicht erfüllt, wird stattdessen Anweisung_2 ausgeführt.
Zwar kann der ELSE-Zweig mit der Anweisung_2 auch ganz weggelassen werden. Es ist aber guter Programmierstil, wenn man bei jeder Entscheidung beide Möglichkeiten explizit "ausprogrammiert"; auf diese Weise vermeidet man logische Lücken im Programm.


Ein Beispiel:

Ein Programm soll entscheiden, ob eine eingegebene Zahl größer, kleiner oder gleich Null ist. Ehe Sie jetzt sagen, dass Sie das selbst entscheiden können und dazu kein Programm brauchen, sollten Sie zur Kenntnis nehmen, dass man an einem solchen überschaubaren Beispiel tatsächlich einiges lernen kann. Schauen wir es uns also genauer an:
In Delphi benutzen wir für die Eingabe der Zahl ein TEdit-Feld Edit1, für die Ausgabe des Antworttextes ein TEdit-Feld Edit2. Und natürlich braucht unser Programm noch einen Knopf, der die Aktion auslöst. In dessen Klick-Prozedur könnte dann folgendes stehen:
        var n : Integer;
        begin
        n := StrToInt(Edit1.Text);
        If n > 0 then
          Edit2.Text := 'Diese Zahl ist positiv.'
        else
          if n < 0 then
            Edit2.Text := 'Diese Zahl ist negativ.'
          else 
            Edit2.Text := 'Diese Zahl ist Null.';
        end;
Dazu ein paar Bemerkungen und Ergänzungen:
  • Die Bedingung einer "if-else"-Anweisung kann ein Vergleich zweier Zahlen sein. Neben den hier benutzten Vergleichsoperatoren ">" und "<" können Sie auch die folgenden Operatoren benutzen:
    größer oder gleich ">="
    kleiner oder gleich "<="
    gleich "="
    Weitere Möglichkeiten werden wir später kennenlernen.

  • Wenn das Programm einen Text ausgeben soll, dann muss dieser im Programm-Code in Hochkommata ('einfache' Anführungszeichen) eingeschlossen werden. Geben Sie Texte in "normale" Edit-Komponenten aus, deren "Read-Only"-Eigenschaft Sie auf "True" setzen. Alternativ können Sie auch eine TLabel-Komponenten benutzen und den Text in deren "Caption" ausgeben.

  • Sowohl im "if"-Teil als auch im "else"-Teil der Entscheidung steht jeweils nur eine Anweisung. Allerdings kann die Anweisung selbst wieder zusammengesetzt sein: hier z.B. steht im "else"-Teil der Entscheidung wieder eine komplette Entscheidung!

  • Wenn irgendwann mal der Fall auftaucht, dass Sie im "if"- oder "else"-Teil einer Entscheidung wirklich mehr als eine Anweisung brauchen, können Sie von der "universellen gegenseitigen Einsetzbarkeit" der elementaren Programmierstrukturen Gebrauch machen: verwenden Sie einfach eine Sequenz! In Delphi/Pascal ist eine Sequenz eine Folge von Anweisungen, die durch "begin" und "end" eingeklammert sind. Ein solcher "Block" gilt - von außen gesehen - ebenfalls als eine Anweisung.
In Java benutzen wir für die Eingabe der Zahl ein Text-Feld textField1, für die Ausgabe des Antworttextes ein Text-Feld textField2. Und natürlich braucht unser Programm noch einen Knopf, der die Aktion auslöst. In dessen Klick-Prozedur könnte dann folgendes stehen:
        int n = Integer.parseInt(textField1.getText());
        if (n > 0) {
          textField2.setText("Diese Zahl ist positiv.");
        } else {
          if (n < 0) {
            textField2.setText("Diese Zahl ist negativ.");
          } else {
            textField2.setText("Diese Zahl ist Null.");
          };
        };
Dazu ein paar Bemerkungen und Ergänzungen:
  • Die Bedingung einer "if-else"-Anweisung kann ein Vergleich zweier Zahlen sein. Neben den hier benutzten Vergleichsoperatoren ">" und "<" können Sie auch die folgenden Operatoren benutzen:
    größer oder gleich ">="
    kleiner oder gleich "<="
    gleich "=="
    Weitere Möglichkeiten werden wir später kennenlernen.

  • Wenn das Programm einen Text ausgeben soll, dann muss dieser im Programm-Code in Anführungszeichen (doppelte Anführungszeichen) eingeschlossen werden. Geben Sie Texte in "normale" textField-Komponenten aus, deren "Editable"-Eigenschaft Sie auf "False" setzen. Alternativ können Sie auch eine Label- oder JLabel-Komponente benutzen und den gewünschten Text (im Objekt-Inspektor) in deren Eigenschaft "Text" eintragen bzw. (zur Laufzeit) mit der Methode "setText()" ausgeben.

  • Sowohl im "if"-Teil als auch im "else"-Teil der Entscheidung kann statt nur einer Anweisung auch eine ganze Sequenz stehen, wenn diese mit geschweiften Klammern ( { und } ) eingeschlossen wird: diese dienen der Klammerung eines "Blocks", welcher dann - von außen gesehen - ebenfalls als nur eine Anweisung zählt. Wenn Sie aber wirklich nur eine Anweisung im "if"- oder "else"-Teil brauchen, dann können Sie die zugehörigen geschweiften Klammern auch weglassen. Allerdings fügen viele Java-Editoren sie schon automatisch ein, wenn Sie beginnen, eine Entscheidung in Ihren Quelltext einzutippen. Um Ihre Programme leichter lesbar und wartbar zu halten, rate ich Ihnen, diese Klammern in der Regel stehen zu lassen.



Mit diesen Informationen sollten Sie nun den folgenden Aufgaben gewachsen sein:


  1. Das Mengenstaffel-Problem:

    Ein Computerladen verkauft CD-Rohlinge in Packungen zu je 10 Stück. Für Großabnehmer gibt's Rabatt. Die ersten 5 Packungen kosten € 6,90, die nächsten 10 nur noch € 5,90, und ab der 16. kostet die Packung nur noch € 4,90. Schreiben Sie ein Programm, das nach Eingabe der Anzahl gekaufter Packungen den zu zahlenden Betrag ausgibt.

    (Ein Tipp: Zur Vereinfachung können Sie sich in einer ersten
    Version auf Anzahlen kleiner als 16 beschränken.)
    Lösungsvorschlag: [Delphi] [Java]



Eine Klick-Prozedur lässt sich in vielen Fällen so strukturieren, dass sie in drei wohlunterscheidbare Teile zerfällt: einen Eingabeteil, einen Verarbeitungsteil und einen Ausgabeteil. Diese nicht immer, aber doch recht häufig verwendete Struktur trägt den schönen Namen "EVA-Prinzip". Wenn wir dieses Prinzip auf das "Größer/gleich/kleiner Null"-Beispiel vom Anfang dieses Kapitels anwenden wollen, dann könnte die Klickprozedur des Knopfes etwa so aussehen:
In Delphi:
  procedure Button1Click(Sender: TObject);
    var n : Integer;
        s : String;
    begin 
    { "E"ingabe =======================}
    n := StrToInt(Edit1.Text);

    { "V"erarbeitung ==================}
    If n > 0 then
      s := 'Diese Zahl ist positiv.'
    else
      if n < 0 then
        s := 'Diese Zahl ist negativ.'
      else 
        s := 'Diese Zahl ist Null.';

    { "A"usgabe =======================}
    Edit2.Text := s;
    end;
Beachten Sie auch, wie Kommentare in den Quelltext eingefügt werden können: sie sind stets von { und } (also von geschweiften Klammern) umschlossen! Innerhalb eines Kommentars sind (nahezu) alle Zeichen erlaubt - außer eben geschweiften Klammern!
In Java:
  public void button1_ActionPerformed(ActionEvent evt) {

    /* "E"ingabe ======================= */
    int n = Integer.parseInt(textField1.getText());
    String s;

    /* "V"erarbeitung ================== */
    If (n > 0) {
      s = "Diese Zahl ist positiv.";
    } else {
      if (n < 0) {
        s = "Diese Zahl ist negativ.";
      } else {
        s = "Diese Zahl ist Null.";
      }
    }

    /* "A"usgabe ======================= */
    textField2.setText(s);
  };
Beachten Sie auch, wie Kommentare in den Quelltext eingefügt werden können: sie sind stets von /* und */ eingeschlossen! Innerhalb eines Kommentars sind (nahezu) alle Zeichen erlaubt - außer eben /* und */ !

Vielleicht hilft Ihnen das EVA-Prinzip bei der Bearbeitung der weiteren Aufgaben:



  1. Das Lineare Problem:

    Eine lineare Gleichung (a*x = b) kann eine, keine oder unendlich viele Lösungen haben, je nach den Werten von a und b. Schreiben Sie ein Programm, das nach Eingabe der Werte für a und b auf Knopfdruck in allen möglichen Fällen korrekt und vollständig Auskunft gibt über die Lösungsmenge der jeweiligen Gleichung. Die Ausgabe kann z.B. in einem normalen Edit-Feld geschehen, dessen ReadOnly-Eigenschaft auf True gesetzt wird, sodass der Benutzer dort nichts eingeben kann.
    Lösungsvorschlag: [Delphi] [Java]


  2. Das Quadratische Problem (für Fortgeschrittene):

    Eine quadratische Gleichung (a*x^2 + b*x + c = 0) kann keine, eine oder zwei Lösungen haben, je nach dem Vorzeichen der Diskriminante D = b^2 - 4ac. Schreiben Sie ein Programm, das nach Eingabe der Werte für a, b und c auf Knopfdruck in allen möglichen Fällen korrekt und vollständig Auskunft gibt über die Lösungsmenge der jeweiligen Gleichung.

    (Beachten Sie: Im Fall a = 0 liegt das "lineare Problem" aus der vorigen Aufgabe vor. Ihr Programm kann diesen Fall mit einer Fehlermeldung zurückweisen; setzen Sie dann beim Schließen den Fokus wieder ins "a"-Eingabefeld. Richtig gut ist das Programm aber erst, wenn es auch in diesem Fall stets die mathematisch korrekte Antwort weiß.)
    Lösungsvorschlag: [Delphi] [Java]


  3. Das Kopfrechen-Trainer-Problem (für besonders Kreative):

    Ein Programm soll selbständig einfache Additionsaufgaben "erzeugen", Lösungsvorschläge vom Benutzer entgegennehmen und auf Richtigkeit überprüfen. Ist die Lösung richtig, soll der Benutzer zunächst gelobt und dann mit einer neuen Aufgabe versorgt werden; ist sie falsch, soll er nur darauf hingewiesen werden.

    Beim Erzeugen der Additionsaufgaben muss das Programm selbständig 2 Summanden wählen. Dies ist für ein Programm eine schwierige Aufgabe, denn Programme arbeiten stets vollkommen deterministisch: einen "echten Zufall" kann es in einem Algorithmus eigentlich überhaupt nicht geben! Glücklicherweise gibt es aber Algorithmen, die Zahlenfolgen generieren, welche kaum von Zufallsfolgen zu unterscheiden sind.
    In Delphi gibt es zum Abruf von (Pseudo-)Zufallszahlen die RANDOM()-Funktion: RANDOM(25) liefert eine Integerzahl im Bereich {0; 1; 2;....23; 24}. Wenn Sie für die Summanden zwei Integer-Variablen s1 und s2 benutzen, können Sie diese mit
        s1 := RANDOM(25) + 1;
        s2 := RANDOM(25) + 1;
    "laden".
    In Java gibt es zum Abruf von (Pseudo-)Zufallszahlen die "Math.random()"-Funktion: sie liefert eine zufällige Double-Zahl aus dem Intervall [0..1). Diese "Quelle" kann man benutzen, um z.B. zufällige Integerzahlen aus dem Bereich {1, 2, 3, 4, ... 24, 25} zu generieren. Wenn Sie für die Summanden zwei Integer-Variablen s1 und s2 benutzen, können Sie diese mit
        s1 = (int) (Math.random() * 25) + 1;
        s2 = (int) (Math.random() * 25) + 1;
    "laden".
    Beachten Sie, dass s1 und s2 danach in der Regel durchaus verschiedene Werte enthalten, weil die Zufalls-Funktion bei jedem Aufruf eine neue Zufallszahl erzeugt! Durch das " + 1 " vermeiden Sie den Summanden 0, was ja zu gar zu einfachen Aufgaben führen würde!

    Diese Programmieraufgabe bietet viele individuelle Gestaltungs- und Erweiterungsmöglichkeiten. Wenn Sie Spaß daran haben, können Sie die folgenden Anregungen bearbeiten:

    • Lösen Sie die Beurteilung des Lösungsvorschlags durch das Drücken der ENTER-Taste direkt nach der Eingabe aus!
    • Setzen Sie nach der Erzeugung einer neuen Aufgabe den Fokus automatisch auf das Eingabefeld für den Lösungsvorschlag.
    • Zählen Sie die richtigen und die falschen Lösungsvorschläge mit (in zwei "privaten" Integer-Variablen des Formulars), und geben Sie am Schluss des Programmlaufs eine Bilanz aus!
    • Erweitern Sie das Programm für verschiedene Schwierigkeitsstufen (durch Wahl des Zahlbereichs für die Summanden) und / oder andere Rechenarten...



Zum vorigen Kapitel Zum Inhaltsverzeichnis Zum nächsten Kapitel