Advanced   Java   Services Kontrollstrukturen 1 Back Next Up Home

if/else

if bzw. if/else ist die einfachste Kontrollstruktur. Mit ihr formuliert man eine wenn/dann Entscheidung. Wenn die im Booleschen Ausdruck formulierte Bedingung erfüllt ist (true), dann werden eine oder mehrere Anweisungen ausgeführt. Ist die Bedingung nicht erfüllt (false), so wird keine der Anweisungen ausgeführt.


Unvollständige if-Entscheidung
if ( BoolescherAusdruck )
   eineAnweisung ;

oder

if ( BoolescherAusdruck )
{
   anweisung1 ;
   anweisung2 ;
   // beliebig viele Anweisungen
}

Vollständige if-Entscheidung
if ( BoolescherAusdruck )
   anweisung1 ; // true-Zweig
else
   anweisung2 ; // false-Zweig

bzw.

if ( BoolescherAusdruck )
{
   anweisung1 ;
   anweisung2 ;
   // beliebig viele Anweisungen im true-Zweig
}
else
{
   anweisung1 ;
   anweisung2 ;
   // beliebig viele Anweisungen im false-Zweig
}

Ist bei der vollständigen Fallunterscheidung die Bedingung erfüllt, so wird der true-Zweig abgearbeitet, ist die Bedingung nicht erfüllt wird der false-Zweig abgearbeitet.

Beispiele

if (temperatur < -10)
   System.out.println("saukalt");

if (zahl%2 == 0)
   System.out.println(zahl+" ist gerade");
else
   System.out.println(zahl+" ist ungerade");

Die Grundstruktur von if/else ist nicht schwer, da diese jedoch beliebig tief verschachtelt werden kann, können damit sehr komplexe Strukturen aufgebaut werden. Zudem kann der boolesche Ausdruck, also die Bedingung, auch aus mehreren Teilaudrücken zusammengesetzt sein, sodaß auch dadurch schwierig zu durchschauende Abläufe entstehen können.


Zweimal if oder einmal if/else ?

Am Anfang neigt man dazu, lieber öfters  if  einzusetzen statt eines vollständigen  if/else  . Es gibt Situationen, wo einem der Compiler darauf hinweist, daß hier ein logischer Unterschied besteht.

int a, abs ;
a = Stdin.intEingabe();

if ( a < 0 )
   abs = -a ;

if ( a >= 0 )
   abs = a ;

System.out.println("abs =" + abs);

Hier wird die Variable abs in Abhängigkeit von a belegt und es sieht auf den ersten Blick alles gut aus. Trotzdem erhält man beim compilieren die Fehlermeldung Variable abs might not have been initialized. Dagegen wird die folgende Variante vom Complier nicht beanstandet:

int a, abs ;
a = Stdin.intEingabe();
if ( a < 0 )
   abs = -a ;
else
   abs = a ;

System.out.println("abs =" + abs);

Der Compiler prüft nicht die Bedingungen in if, sondern nur ob eine if-Anweisung logisch vollständig ist. Bei zwei unvollständigen if-Anweisungen kann es durchaus vorkommen, daß die Variable nicht für jeden Fall eine Wertzuweisung erhält, wie die folgende Variante zeigt, bei der b für den Fall, daß a den Wert 0 hat, nicht belegt ist.

int a, b ;
a = Stdin.intEingabe();

if ( a < 0 )
   b = -a ;

if ( a > 0 )
   b = a ;

verwendet man dagegen if/else, kann so ein Fehler nicht vorkommen.


Schachtelung von if/else

Bei der Schachtelung von if/else muß man genau darauf achten, welches else zu welchem if gehört und dies durch Einrückung und/oder Klammerung deutlich machen.

if (a <= b)
   if (b <= c)
      max = c ;
   else  // b > c
      max = b ;

else  // a > b
   if (c >= a)
      max = c ;
   else  // c < a
      max = a ;

Dem Compiler ist es egal, ob man einrückt oder nicht. Er ordnet ein else immer dem nächsten freien if zu, das er nach oben findet. Nach dieser Regel wird in obigem Beispiel das erste else dem zweiten if zugeordnet und das zweite else dem dem ersten if und schließich das dritte else dem dritten if. Will man diese Zuordnung verhindern, muß man Blockklammern setzen, was natürlich im obigen Beispiel, das das Maximum von drei Zahlen a, b und c bestimmt, nicht sinnvoll ist.

Manchmal ist die automatische Zuordnung des Compilers nicht erwünscht. In diesem Fall setzt man Blockklammern, um die beabsichtigte Zuordnung zu erreichen, also nicht so :

if ( monat == 12 )
   if ( temp > 15)
      System.out.println("Sehr warm für Dezember") ;
   else
      System.out.println("Der Weihnachtsmann kommt nicht") ;

sondern so

if ( monat == 12 )
{
   if ( temp > 15)
      System.out.println("Sehr warm für Dezember") ;
}
else
   System.out.println("Der Weihnachtsmann kommt nicht") ;

Ein beliebter Fehler sind else-Zweige, die der Compiler keinem if zuordnen kann (else without if). Oft entsteht dieser Fehler dadurch, daß die Blockklammern vergessen wurden. Im folgenden Beispiel ist der true-Zweig mit der ersten Anweiszung zu Ende. Die zweite Anweisung hat nichts mehr mit if zu tun, deswegen findet der Compiler zu else kein if.

if ( ... )
   anweisung1  ;
   anweisung2  ;
else
   anweisung3 ;

Richtig lautet es folgendermaßen

if ( ... )
{
   anweisung1  ;
   anweisung2  ;
}
else
   anweisung3 ;

else-if Ketten

Oft muß man else und if direkt hintereinander schachteln. Man erhält dadurch eine ganze Kette von else if Abfolgen.

if ( monat >=1 && monat < 4)
   System.out.println("naß und kalt") ;

else if (monat >=4 && monat < 6)
   System.out.println("Frühling") ;

else if (monat >=6 && monat < 9)
   System.out.println("Sommer") ;

else if (monat >=9 && monat < 12)
   System.out.println("Herbst") ;

else if (monat == 12)
   System.out.println("Winter") ;

else
   System.out.println("mehr Monate gibt es nicht !") ;

In bestimmten Situationen kann man die else-if Kette ersetzen durch eine Mehrfachverzweigung mit switch.


switch

Bei dieser Mehrfachverzweigung wird ein numerischer Ausdruck mit Konstanten verglichen. Wird eine Übereinstimmung gefunden, so wird die zur Konstanten gehörige Anweisung und sämtliche darauffolgenden Anweisungen ausgeführt. Die Konstanten stehen zwischen dem Schlüsselwort case und einem Doppelpunkt.

switch( numerischer_Ausdruck )
{
   case konstante1 : anweisung ;
                     weitere_anweisung ;

   case konstante2 : anweisung ;
                     weitere_anweisung ;

   // beliebig viele case-Zweige
   // jede konstante kann nur einmal vorkommen

   default : anweisung ;
             weitere_anweisung ;
}

Einige wichtige Regeln zu switch

Der erste Versuch, die obige else-if Kette in eine switch-Anweisung zu verwandeln könnte so aussehen:

switch( monat )
{
   case  1 :
   case  2 :
   case  3 : System.out.println("naß und kalt") ;

   case  4 :
   case  5 :
   case  6 : System.out.println("Frühling") ;

   case  7 :
   case  8 : System.out.println("Sommer") ;

   case  9 :
   case 10 :
   case 11 : System.out.println("Herbst") ;

   case 12 : System.out.println("Winter") ;

   default : System.out.println("Mehr Monate gibt es nicht !") ;
}

Die Marken von switch sind jedoch nicht exklusiv. Eingangs wurde bereits geschrieben : Wird eine Übereinstimmung gefunden, so wird die zur Konstanten gehörige Anweisung und sämtliche darauffolgenden Anweisungen ausgeführt. So führt etwa der Wert 5 für Monat zu folgender Ausgabe:

Frühling
Sommer
Herbst
Winter
Mehr Monate gibt es nicht !

Abhilfe schafft die break-Anweisung, wenn man sie jeweils als letzte Anweisung in case setzt :

switch( monat )
{
   case  1 :
   case  2 :
   case  3 : System.out.println("naß und kalt") ;
             break;
   case  4 :
   case  5 :
   case  6 : System.out.println("Frühling") ;
             break;
   case  7 :
   case  8 : System.out.println("Sommer") ;
             break;
   case  9 :
   case 10 :
   case 11 : System.out.println("Herbst") ;
             break;
   case 12 : System.out.println("Winter") ;
             break;
   default : System.out.println("Mehr Monate gibt es nicht !") ;
}

bedingte Zuweisung und bedingter Ausdruck ( ? : - Operator )

Einfache if/else Verzweigungen kann man oft sehr kurz mit Hilfe eines bedingten Ausdrucks formulieren. Er hat die Form

BoolescherAusdruck  ?  trueAusdruck  :  falseAusdruck

Obwohl die Klammern nicht notwendig sind, setzt man sie wegen der Lesbarkeit gerne.

(BoolescherAusdruck)  ?  trueAusdruck  :  falseAusdruck

Da Ausdrücke in Java nicht als Anweisungen verwendet werden dürfen, muß der bedingte Ausdruck zugewiesen werden, also etwa so

var = BoolescherAusdruck  ?  trueAusdruck : falseAusdruck ;

Man kann den bedingten Ausdruck auch in einen Methodenaufruf stecken, aber da wird er ja auch einer lokalen Variablen zugewiesen.

So kann man etwa die Bestimmung des Maximums zweier Zahlen

if (a < b)
   max = b;
else
   max = a;

kürzer und eleganter auch so schreiben:

max = a < b  ?  b : a ;

Wie if/else, so kann auch der bedingte Ausdruck geschachtelt werden, hier als Beispiel die Bestimmunmg des Vorzeichens einer Zahl zuerst mit if/else, dann mit einem bedingten Ausdruck.

if (x < 0)
   sgn = -1;
else if (x > 0)
   sgn = 1;
else
   sgn = 0;

Und jetzt mit einem bedingtenm Ausdruck

sgn = x < 0  ?  -1 : x > 0  ?  1 : 0 ;

Der bedingte Ausdruck wird mit Hilfe des ternären Operators ?: gebildet. Er steht auf der zweitniedrigsten Prioritätsstufe.


Welche Datentypen dürfen verwendet werden ?

Wir betrachten noch einmal die am meisten verwendete Form

var = BoolescherAusdruck  ?  trueAusdruck  :  falseAusdruck ;

Folgendes gilt es zu beachten:

Beispiel:

  1. double x ; int a = 4; long b = 5 ;
    x = a < b ? a : b ;

  2. long x ; int a = 4; double b = 5 ;
    x = a < b ? a : b ;

Das erste Beispiel ist in Ordnung, das zweite nicht. Überlegen Sie, was falsch ist.


Übungen

Wochentag zum Datum

Wann ist Ostern

Valid XHTML 1.0 Strict top Back Next Up Home