3.1 Verzweigungen und Vergleichsoperationen
3.1 Verzweigungen und VergleichsoperationenDurch Verzweigungen können im Ablauffluß des Programmes verschiedene Fälle geprüft werden und man kann abhängig davon unterschiedliche Anweisungen ausführen.
Befehlsblöcke
Java erlaubt das Zusammenfassen von Javabefehlen durch Blöcke. Blöcke werden geschweiften Klammern beschrieben.
Für Blöcke gilt
- Im Block deklarierte Variablen sind nur innerhalb des Blocks, nach der Deklaration benutzbar
- Befehle innerhalb eines Blocks müssen mit Semikolon getrennt werden
- Auch der letzte Befehl in einem Block muss mit Semikolon abgeschlossen werden
- Blöcke können geschachtelt werden
Beispiel
{ int i = 1; i++; int j = i*2; }
Tipp: Systematisches Einrücken und Klammern die genau übereinander stehen helfen sehr bei der Lesbarkeit
Einfachverzweigung (if, if else)
Eine Einfachverzweigung wird in Java mit dem Schlüsselwort if eingeleitet. Anschließend folgt eine Bedingung in runden Klammern. Ist die Bedingung erfüllt, wird die folgende Anweisung bzw. der Anweisungsblock in geschweiften Klammern ausgeführt. Hierdurch ergibt sich die folgende Syntax:
if (Bedingung) Anweisung;
oder
if (Bedingung) {Anweisung(en);}
Ist die Bedingung nicht erfüllt wird die Anweisung ausgelassen und der normale Ausführungsfluß wird wieder aufgenommen. Ein Beispiel hierfür ist:
int x = 8; if (x > 5) System.out.println("Wert x = " + x + " ist größer als 5"); System.out.println ("Wert x = " + x);
Hier ergeben sich die Ausgaben:
Wert x = 8 ist größer als 5 Wert x = 8
da die bedingte Anweisung sowie die letzte Anweisung durchlaufen wird.
UML Darstellung in Aktivitätsdiagrammen
if Bedingung ohne else Klausel kann man die geschweiften Klammer bei einer einzelnen Anweisung weglassen.
Entweder-oder Kontrollfluss mit dem Schlüsselwort else
Es gibt auch die Möglichkeit eines entweder-oder Kontrollflusses mit Hilfe des Schlüsselworts else:
if (Bedingung) {Anweisung(en);} else {Anweisung(en);};
Hier wird der eine oder der andere Block von Anweisungen ausgeführt.
Ein Beispiel:
int x = 8; int y = 0; if (x > 5) { System.out.println("Wert x = " + x + " ist größer als 5"); y = x; } else { System.out.println("Wert x = " + x + " ist kleiner oder gleich 5"); y = -x; } System.out.println ("Wert x = " + x );
UML Darstellung in Aktivitätsdiagrammen
if Anweisungen lassen sich schachteln um komplexe Bedingungen prüfen zu können. Anbei ein Beispiel:
int a = 5; int b = 10; int maximum =0; if (a > b) // Äussere if Bedingung if (a > 0) { maximum = a;} // Innere if Bedingung else { maximum = 0; } //innere else Bedingung System.out.println ("Wert maximum = " + maximum "); |
Im oben gezeigten Beispiel gibt es eine else Bedingung von der es nicht offensichtlich ist zu welchem if Block sie gehört.
else-Regel |
---|
Ein else-Block gehört immer zum direkt vorhergehenden if-Block |
Tipp: Der Quellcode wird bei geschachtelten if Bedingungen schnell unübersichtlich und fehleranfällig.
Verwenden Sie besser die im Folgenden vorgestellte switch Bedingung um komplexe Abfragen zu implementieren.
Mehrfachverzweigung (switch-case)
Eine Alternative zu if-else Anweisungen ist die switch-case Anweisung. Sie erlaubt eine sehr viel übersichtlichere Programmierung wenn es bei einem ganzzahligen Ausdruck mehr als zwei Alternativen gibt.
Im einfachen Fall sieht eine switch-case Anwendung wie folgt aus:
int wochentag; ... switch (wochentag) { case 7: System.out.println("Sonntag"); break; case 6: System.out.println("Samstag"); break; case 5: case 4: case 3: case 2: case 1: System.out.println("Wochentag"); break; default: System.out.println("Fehler"); } |
int wochentag; ... switch (wochentag) { case 7: System.out.println("Sonntag"); break; case 6: System.out.println("Samstag"); break; case 5: case 4: case 3: case 2: case 1: System.out.println("Wochentag"); break; default: System.out.println("Kein gültiger Wochentag!"); }
Besonderheiten der switch-case Anweisung
- Der zu prüfende Ausdruck muss bestimmten Typen genügen:
- byte, short, int, char, enum, String. (Die Unterstützung von String ist neu seit JDK 7, siehe JSR 334, Projekt Coin)
- Die einzelnen Fälle (cases) werden nicht mit geschweiften Klammern geklammert
- Das Schlüsselwort break dient zum Rücksprung aus einem Fall. Der nächste Fall wird mit abgearbeitet wenn es weggelassen wird!
- Es können mehrere Fälle mit Doppelpunkt aufgeführt werden. Der darauf folgende Block wird dann für alle Fälle abgearbeitet.
- Das Schlüsselwort default erlaubt einen Ausführungsblock anzugeben, der ausgeführt wird wenn kein anderer Fall zum Zuge kam
- Der Wert in einem Fall (case) muss eine Konstante sein.
Allgemeine Form:
... switch (Ausdruck) { case konstante1: Anweisung(en); break; ... case konstante2: case konstante3: ... case konstanteN: Anweisung(en); break; default: Anweisung(en); break; }
Beispiel mit unterschiedlichen Break-Anweisungen
int wochentag; ... switch (wochentag) { case 7: System.out.println("Sonntag"); break; case 6: System.out.println("Samstag"); case 5: case 4: case 3: case 2: case 1: System.out.println("Wochentag"); break; default: System.out.println("Fehler"); } |
- 14423 views
Fehlende break; - Anweisung
Fehlt die break;-Anweisung, werden die folgenden Blöcke ohne Fallüberprüfung ausgeführt? Im UML-Diagramm ("Beispiel mit untersch. Break-Anweisungen) ist dargestellt, dass im case 6: automatisch auch die cases 5-1: angenommen werden und somit "Samstag" UND "Wochentag" gedruckt werden würden.
Ist das tatsächlich der Fall, oder werden die folgenden Cases trotz fehlender break-Anweisung zumindest geprüft? Das "der nächste Fall wird mitabgearbeitet" ist etwas undeutlich formuliert.
Besten Dank
Gut beobachtet
Ja, fehlt ein break, läuft das Programm einfach weiter. Zur Formulierung muss ich erst nochmal nachdenken.
Einfach ausprobieren in der JS-Konsole (mit: console.log)
wochentag=6
switch (wochentag) {
case 7:
console.log("Sonntag");
break;
case 6:
console.log("Samstag");
case 5: case 4: case 3: case 2: case 1:
console.log("Wochentag");
break;
default:
console.log("Fehler");
}
=>
Samstag
Wochentag
break-Schlüsselwort nach default
Im Bsp unter "Besonderheiten der switch-case Anweisung" wird die default-Anweisung mit einem "break;" beendet, im "Beispiel mit unterschiedlichen Break-Anweisungen" jedoch ohne.
Unterliegt beides der korrekten Syntax?
Gruß.
Beides ist OK
... solange die default Klausel die letzte ist.
Gut beobachtet
Ja, das ist Geschmackssache.
Bei Ihrem Beispiel mit…
Bei Ihrem Beispiel mit verschachtelten if und else Strukturen ist bei dem System.out.println("Wert maximum: " + maximum"); hinter dem letzten Maximum noch ein Anführungszeichen, welches gelöscht werden muss.
Stimmt
Danke.