Fallunterscheidungen
Computerprogramme bestehen aus einer Folge von Anweisungen, die nacheinander ausgeführt werden. Das Programm aus Folge 3 "Sie werden gewogen" läuft zum Beispiel so ab:
1.) Gewicht ermitteln
2.) Körpergröße feststellen
3.) Idealgewicht berechnen
4.) Differenz Gewicht - Idealgewicht berechnen und ausgeben
Häufig müssen Computerprogramme aber auch Entscheidungen treffen. Dazu testen sie bestimmte Bedingungen und führen - abhängig vom Ergebnis des Tests - bestimmte Aktionen durch.
In einer der Übungen aus Folge 3 sollen Sie das Programm so verfeinern, dass in dem Ausgabefenster angezeigt wird, ob die Person Übergewicht, Untergewicht oder Idealgewicht hat. Dazu ist eine dreiseitige Fallunterscheidung oder eine so genannte Dreifachauswahl notwendig. Ein Mensch hat keine Probleme, eine solche Auswahl zu treffen, ein Computer schon. Die gängigen Programmiersprachen kennen nämlich nur die einseitige Auswahl sowie die zweiseitige Auswahl, mit denen wir uns im Folgenden näher beschäftigen wollen. Anschließend kommen wir auf die Frage zurück, wie man mit diesen einfachen Mitteln eine dreiseitige Auswahl realisieren kann.
Die einseitige Auswahl oder
Die if-AnweisungEine if-Anweisung besteht aus dem Schlüsselwort "if" - klein geschrieben - einer logischen Bedingung, die in runden Klammern stehen muss, und einer einzelnen Anweisung oder einer Anweisungsliste:
1 Syntaxdiagramm der if-Anweisung
Die logische Bedingung
Eine logische Bedingung ist immer entweder wahr (true) oder falsch (false). Im Gegensatz zur Sprache C++ akzeptiert Java hier keine numerischen Ausdrücke; in den Klammern muss also wirklich ein boolean-Ausdruck stehen. Es folgen nun einige Beispiele für korrekte boolean-Ausdrücke:
x == 3
y < z + 3
radius + 2 <= aussenradius - 2
Einfache boolean-Ausdrücke bestehen also aus einer rechten Seite, einem logischen Operator (siehe Randspalte) und einer linken Seite. Die rechte und die linke Seite werden miteinander verglichen. Jenachdem, wie dieser Vergleich ausfällt, nimmt dann der gesamte boolean-Ausdruck den Wert true oder false an.
Eine korrekte if-Anweisung könnte demnach so aussehen:
if (x == 3) System.out.println("x ist 3");
Vergessen Sie nie(!) dass die logische Bedingung in runden Klammern stehen muss.
Kompliziertere logische Bedingungen
Oft reichen einfache logische Bedingungen nicht für unsere Zwecke aus. Soll zum Beispiel überprüft werden, ob eine Zahl x im Intervall [10..20] liegt, so muss man schreiben:
if ((x >= 10) && (x <= 20)) Anweisungsliste;
Hier muss man auf die korrekte Klammerung achten, da der &&-Operator eine höhere Priorität hat als die Vergleichsoperatoren >= bzw. <=.
Die Anweisungsliste

2 Syntaxdiagramm der Anweisungsliste
Auf die logische Bedingung folgt bei einer if-Anweisung eine Anweisungsliste. Unter einer Anweisungsliste verstehen wir
entweder eine einzelne Anweisung, gefolgt von einem Semikolon (obere Zeile des Diagramms)
oder eine in geschweiften Klammern stehende Liste von Anweisungen, wobei am Ende jeder Anweisung ein Semikolon stehen muss
Korrekte Anweisungslisten wären also z.B.:
System.out.println("korrekt");
oder
i = i + 5;
oder
{
System.out.println("korrekt");
y = 20; z = 40+y;
}
Verwendung der einseitigen Auswahl
Die einseitige Auswahl wird verwendet, wenn man eine Aktion nur dann durchführen möchte, wenn eine bestimmte Bedingung erfüllt ist, und wenn man für den Fall, dass die Bedingung nicht erfüllt ist, keine alternative Aktion geplant hat.
Angenommen, Sie wollen bereits während des Wiegens eine Meldung ausgeben lassen, falls die Person eindeutig zu schwer ist, so könnten Sie schreiben:
public void wiegen(int messwert)
{
gewicht = messwert;
if (messwert > 120)
System.out.println
("Bitte nur eine Person auf die Waage stellen!");
}
Die zweiseitige Auswahl oder
Die if-else-Anweisung
Meistens hat man aber eine alternative Aktion geplant, wenn die Bedingung für die Hauptaktion nicht erfüllt ist. Für eine solche zweiseitige Auswahl verwendet man die if-else-Anweisung, die im Prinzip genauso aufgebaut ist wie die if-Anweisung.

3 Syntaxdiagramm der if-else-Anweisung
Das, was bereits über logische Bedingungen und Anweisungslisten gesagt wurde, bleibt weiterhin gültig. Für Pascal-Programmierer ungewohnt ist vielleicht, dass am Ende des then-Zweigs (in Java gibt es das Schlüsselwort "then" nicht!) ein Semikolon stehen muss. Schauen wir uns eine korrekte if-else-Anweisung an:
if (gewicht <= ideal+3)
System.out.println("Super!);
else
{
System.out.println("Weniger essen!");
diff = gewicht-ideal;
System.out.println(diff + " kg zuviel!");
}
In der ersten Alternative (Pascal-Programmierer würden sagen: "im then-Zweig") haben wir eine einfache Anweisung verwendet, in der zweiten Alternative ("else-Zweig) eine aus drei Anweisungen bestehende Anweisungsliste.
Die dreiseitige Auswahl oder
Geschachtelte if-Anweisungen
Die meisten Programmiersprachen kennen nur ein- oder zweiseitige Auswahlen. Benötigt man eine dreiseitige Auswahl, so sollte man sich die Syntaxdiagramme der ein- und zweiseitigen Auswahl mal näher anschauen. Betrachten wir noch einmal das Syntaxdiagramm der zweiseitigen Auswahl.

3 Syntaxdiagramm der if-else-Anweisung, zum zweiten
Im else-Zweig finden wir eine Anweisungsliste. Diese Anweisungsliste kann aus einer einzelnen Anweisung oder eine geklammerten Liste von Anweisungen bestehen.
Welche Anweisungen sind hier eigentlich erlaubt? Neben Zuweisungen wie
y = 3 * x;
Funktionsaufrufen wie
ausgabe("Sie haben Untergewicht");
oder
System.out.printeln("Funktionsaufruf");
oder
y = mittelwert(x1,x2,x3);
sind auch Schleifen wie
for (i=1;i<=100;i++) s = s+i;
und if-else-Anweisungen wie
if (gewicht < ideal) unter = true;
erlaubt.
Die Tatsache, dass eine Anweisung auch eine if-else-Anweisung sein darf, eröffnet die Möglichkeit zur Konstruktion verschachtelter if-else-Anweisungen.
Stellen wir uns ein Ratespiel vor. Der Computer hat eine Zufallszahl z ermittelt, und der Benutzer hat eine Ratezahl r eingegeben. Das Programm soll nun eine differenzierte Ausgabe machen, wobei vier Fälle unterschieden werden sollen:
if (r < z/2)
ausgabe("viel zu klein!");
else if (r < z)
ausgabe("zu klein!");
else if (r == z)
ausgabe("geraten!");
else
ausgabe("zu groß);
Hier ist unbedingt auf die korrekte Reihenfolge der einzelnen Abfragen zu achten. Hätte man zum Beispiel am Anfang geschrieben:
if (r < z)
ausgabe("zu klein!");
else if (r < z/2)
ausgabe("viel zu klein!");
dann würde das Programm bei einer Ratezahl r < z/2 eine falsche Meldung ausgeben: Bereits die erste Bedingung r < z wäre erfüllt, und somit würde das Progamm melden "zu klein!" statt "viel zu klein!".
Das Dangling-Else-Problem
Dieser Abschnitt dürfte für alle Schüler(innen) interessant sein, die das Fach Informatik im Abitur belegen wollen. Betrachten Sie bitte folgenden Quelltext:
if (x < 10)
if (y < 10)
ausgabe("O.K.");
else
ausgabe("Falsch!");
Was wird hier ausgegeben? Lassen Sie sich nicht von der Stellung des "else" verwirren! Es wird hier der Eindruck erweckt, dass das "else" zum ersten "if" gehört. Das ist aber nicht der Fall, ein "else" gehört immer zum innersten "if", in unserem Fall also zum zweiten "if". Die Meldung "falsch" wird also ausgegeben, wenn y nicht kleiner als 10 ist.
Dieses hier beschriebene Problem ist als "dangling-else-problem" in der Fachliteratur bekannt geworden. Es ist nicht nur von akademischem Interesse, sondern hat auch durchaus praktische Auswirkungen auf die tägliche Programmierarbeit.
|