[[PageOutline(1-2)]] = Bedingte Ausführung = '''Java Insel:''' [[http://openbook.rheinwerk-verlag.de/javainsel9/javainsel_02_006.htm#mj3530d43fab0c366ff75b1414feef64e3|Bedingte Anweisungen oder Fallunterscheidungen]] Hinweis: Von der in Kapitel ''2.6.3 Der Bedingungsoperator'' beschriebenen Möglichkeit, den ternären Operator ? : für bedingte Anweisungen zu verwenden, wird wegen der schlechten Übersichtlichkeit der Syntax abgeraten. Bezüglich der Performance bringt der Bedingungsoperator im Vergleich zu `if / else` keine Vorteile, da der Compiler den Code ohnehin optimiert. Da die Probleme, die durch Software gelöst werden sollen, üblicherweise nicht durch reine Befehlssequenzen abgebildet werden können, gibt es verschiedene Strukturelemente, die den Programmablauf steuern können. Dies bedeutet, dass in Abhängigkeit von den Eingabedaten, dem aktuellen Programmzustand und anderen Kenngrößen auszuführende Programmteile ausgewählt werden (Alternativen), Programmteile übersprungen (nicht ausgeführt) oder wiederholt ausgeführt werden. Bedingte Anweisungen sorgen dafür, dass in Abhängigkeit vom Wert eines Booleschen Ausdrucks (einer Bedingung) ein Programmteil ausgeführt wird oder nicht. == Ausführen oder Überspringen mit `if` == Nur bei Erfüllung der Bedingung werden die Anweisungen im Anweisungsblock ausgeführt. Eine Bedingung kann entweder zu `true` oder zu `false` ausgewertet werden. Sie ist ein Boolescher Ausdruck, der selbst wieder aus Booleschen Ausdrücken und Operatoren (siehe unten) zusammengesetzt sein kann. Anweisungsblock:: Ein Anweisungsblock wird durch geschweifte Klammern `{}` begrenzt. Anweisungsblöcke kommen nicht nur bei bedingten Anweisungen, sondern auch bei Klassen, Methoden, Schleifen, usw. vor. Es werden stets alle Anweisungen im Anweisungsblock ausgeführt. Ein Anweisungsblock kann noch weitere Anweisungsblöcke enthalten. '''Java Insel:''' [[http://openbook.rheinwerk-verlag.de/javainsel9/javainsel_02_004.htm#mjb044d5eb156360a6192e0bde3eeaceb0|Gruppieren von Anweisungen mit Blöcken]] Allgemeine Form:: {{{ #!java if (Bedingung) { // Anweisungsblock } }}} Beispiel:: {{{ #!java // setzt den Wert von x auf den absoluten Betrag von x und gibt eine Meldung aus // falls x positiv ist (>0), wird die Anweisung übersprungen if (x < 0) { x = -x; System.out.println("x war negativ"); } }}} Die Bedingung ist ein Ausdruck, dessen Wert vom Typ `boolean` ist. Der Ausdruck kann beliebig komplex aufgebaut sein. In Booleschen Ausdrücken werden oft Vergleichsoperatoren und logische Operatoren verwendet, um den zu prüfenden Sachverhalt zu beschreiben. '''Hinweis:''' Bei Anweisungsblöcken, die nur aus einer Anweisung bestehen, dürfen die geschweiften Klammern weggelassen werden. Von dieser Möglichkeit wird dringend abgeraten, da die Wartbarkeit des Codes massiv leidet: Falls zu einem späteren Zeitpunkt ein solcher Block um weitere Anweisungen erweitert werden soll, kann es leicht passieren, dass das Einfügen der Klammern vergessen wird und das Programm einen semantischen Fehler enthält. Solche Fehler sind mitunter sehr zeitaufwändig und damit teuer zu finden. == Vergleichsoperatoren == '''Java Insel:''' [[http://openbook.rheinwerk-verlag.de/javainsel9/javainsel_02_005.htm#mjb37eafd775d803d67baf4aae75ee97d7|Die relationalen Operatoren und die Gleichheitsoperatoren]] Vergleichsoperatoren vergleichen zwei Werte desselben (beliebigen) Typs und liefern als Ergebnis einen Wert des Typs `boolean`. Allgemeine Form:: ''Operand1 Vergleichsoperator Operand2'' Liste der Vergleichsoperatoren mit Beispielen: ||= '''Operator''' =||= '''Bedeutung''' =||= '''true''' =||= '''false''' =|| || == || gleich || 2 == 2 || 2 == 3 || || != || ungleich || 3 != 2 || 2.01 != 2.01 || || < || kleiner als || 2 < 13 || 5 < 1 || || <= || kleiner oder gleich || 1 <= 1 || 4 <= 3 || || > || größer als || 10 > 8 || 8 > 11 || || >= || größer oder gleich || 42 >= 42 || 2.99 >= 3.001 || Vergleichsoperatoren können komplexe Operanden verarbeiten: {{{ #!java boolean b = (32 * x + 14 <= y / 17); }}} === Vergleich von Zeichenketten === Bei den primitiven Datentypen können Vergleiche mit den Operatoren == und != vorgenommen werden. Da es sich bei Strings jedoch um Objekte handelt, und diese beiden Vergleichsoperatoren für Objekte in besonderer Form definiert sind (Vergleich der Referenz), sollte der Vergleich zweier Strings auf inhaltliche Gleichheit mittels [[https://docs.oracle.com/javase/8/docs/api/java/lang/String.html#equals-java.lang.Object-|equals]] erfolgen: {{{ #!java String s1 = "Katrin"; String s2 = "Kathrin"; boolean gleich = s1.equals(s2); // gleich enthält den Wert false }}} == Logische Operatoren == '''Java Insel:''' [[http://openbook.rheinwerk-verlag.de/javainsel9/javainsel_02_005.htm#mje27fd167a2ddda300630b8d5c405d763|Logische Operatoren]] Logische Operatoren dienen der logischen Verknüpfung von booleschen Ausdrücken. Sowohl die Operanden als auch das Ergebnis sind also vom Typ `boolean`. Allgemeine Form:: ''Operand1 Logischer Operator Operand2'' Die wichtigsten logischen Operatoren sind && für Logische UND sowie !|| für logisches ODER. Der Operator ! (NICHT) hat nur einen Operanden und negiert diesen. Wahrheitstabelle für die logische Verknüpfung zweier Operanden A und B vom Typ `boolean`: ||= A =||= B =||= !A =||= A && B =||= A !|| B =|| || false || false || true || false || false || || false || true || true || false || true || || true || false || false || false || true || || true || true || false || true || true || === Logische Operatoren in bedingten Anweisungen === In Bedingungen können mit logischen Operatoren komplexe Zusammenhänge formuliert werden. Allgemeine Beispiele: {{{ #!java if (Ausdruck1 && Ausdruck2) { // Anweisungsblock } if (Ausdruck1 || Ausdruck2) { // Anweisungsblock } if ((Ausdruck1 || (Ausdruck2 && Ausdruck3)) && !Ausdruck4) { // Anweisungsblock } }}} Konkrete Beispiele: {{{ #!java // Falls die Variable a negativ ist, dann wird sie mit -1 multipliziert. if (a < 0) { a = a * -1; } }}} {{{ #!java // Falls beendeProzess() true zurueckgibt, dann wird auf der Konsole "Erledigt." ausgegeben. if (beendeProzess()) { System.out.print("Erledigt."); } }}} {{{ #!java // Falls teilbar(x, 3) true zurueckgibt und die Variable x größer als 42 ist, dann // wird auf der Konsole die Variable x ausgegeben. if (teilbar(x, 3) && x > 42) { System.out.print(x); } }}} {{{ #!java // Falls y größer 0 und kleiner 1 ist, dann liegt es im Intervall. if (y > 0 && y < 1) { System.out.print(y + " liegt im Intervall."); } }}} == Alternative Ausführung mit `if / else` == Bedingte Anweisungen können mit einem alternativen Anweisungsblock versehen werden. Dieser alternative Anweisungsblock wird ausgeführt, wenn die Bedingung '''nicht''' zutrifft, also den Wert `false` hat. Allgemeine Form:: {{{ #!java if (Bedingung) { // Anweisungsblock } else { // Anweisungsblock } }}} Beispiele:: {{{ #!java // y soll der absolute Betrag von x zugewiesen werden if (x < 0) { y = -x; } else { y = x; } }}} Es ist auch möglich, mehrere Alternativen zu formulieren: {{{ #!java // 1, 2, 12: Winter // 3, 4, 5: Frühling // 6, 7, 8: Sommer // 9, 10, 11: Herbst if (monat >= 3 && monat <= 5) { System.out.println("Frühling"); } else if (monat >= 6 && monat <= 8) { System.out.println("Sommer"); } else if (monat >= 9 && monat <= 11) { System.out.println("Herbst"); } else if (monat == 1 || monat == 2 || monat == 12) { System.out.println("Winter"); } else { System.out.println("Fehler"); } }}} == Fallunterscheidung mit `switch / case` == Mit der`switch / case`-Anweisung kann in Abhängigkeit vom Wert eines Ausdrucks ein Fall (`case`) direkt angesprungen werden. Es wird derjenige Fall angesprungen, dessen Wert dem Wert des Ausdrucks in der `switch`-Anweisung gleicht. Als Typen für den Ausdruck sind Ganzzahlen, Zeichen und Zeichenketten (diese erst ab Java Version 7) zulässig. Ab dem angesprungenen `case` wird der gesamte Anweisungsblock der `switch`-Anweisung ausgeführt, '''also auch alle nachfolgenden `case`-Abschnitte. Der Grund dafür ist, dass ein `case` nur eine Sprungmarke ist und nicht den Beginn eines Anweisungsblocks definiert. Daher wird üblicherweise (es gibt sinnvolle Ausnahmen) jeder `case`-Abschnitt mit dem Schlüsselweort `break` abgeschlossen. Dieses verlässt den aktuellen Anweisungsblock, sorgt also dafür, dass die Ausführung hinter der `switch`-Anweisung fortgesetzt wird. Falls keiner der `case`-Abschnitte dem Ausdruck entspricht, wird - sofern vorhanden - der `default`-Abschnitt angesprungen. Allgemeine Form:: {{{ #!java switch (Ausdruck) { // Der Ausdruck hinter dem switch wird jetzt nacheinander mit den hinter der Sprungmarke case // aufgeführten Werten verglichen. Wird kein gleicher Wert gefunden, wird alternativ default ausgeführt. case Wert1: // Anweisungen break; case Wert2: // Anweisungen break; : : : case WertN: // Anweisungen break; default: // Anweisungen } }}} Beispiele:: {{{ #!java // Ausgabe der letzten Stelle einer Zahl als Zahlwort // Nachricht ausgeben und Zahl einlesen System.out.print("Bitte Zahl eingeben: "); zahl = scan.nextInt(); // Zwischenspeicher für das Zahlwort String zahlwort = ""; // letzte Stelle der Zahl entscheidet über das Zahlwort switch (zahl % 10) { case 0: zahlwort = "null"; break; case 1: zahlwort = "eins"; break; case 2: zahlwort = "zwei"; break; case 3: zahlwort = "drei"; break; case 4: zahlwort = "vier"; break; case 5: zahlwort = "fünf"; break; case 6: zahlwort = "sechs"; break; case 7: zahlwort = "sieben"; break; case 8: zahlwort = "acht"; break; case 9: zahlwort = "neun"; break; } System.out.println(zahlwort); }}} Ein Beispiel für sinnvolles Weglassen von `break` {{{ #!java int monat = s.nextInt(); String jahreszeit = ""; switch (monat) { case 3: case 4: case 5: jahreszeit = "Frühling"; break; case 6: case 7: case 8: jahreszeit = "Sommer"; break; case 9: case 10: case 11: jahreszeit = "Herbst"; break; case 1: case 2: case 12: jahreszeit = "Winter"; break; default: jahreszeit = "Diesen Monat gibt es nicht."; } System.out.println(jahreszeit); }}}