Was ist der Unterschied zwischen if / else if und 2x if?
Hallo Community!
Was ich mich beim Programmieren jetzt schon eine Zeit lang frage ist: Was macht es eigentlich für einen Unterschied ob ich schreibe
if(...) {...} if(...) {...}
oder
if(...) {...} else if(...) {...} ?
Danke für alle Antworten! :) Und nein, das ist keine Hausaufgabenfrage! o.O
4 Antworten
Bei "else if (...)" wird die zweite Bedingung nur dann geprüft, wenn die erste Bedingung nicht erfüllt war.
if (a) { it_was_a(); } else if (b) { it_was_b_but_not_a(); }
... ist somit semantisch IN ETWA (nicht ganz, aber fast) vergleichbar mit ...
if (a) { it_was_a(); }
if ((!a) && (b)) { it_was_b_but_not_a(); }
... heißt: Wenn Du das zweite "if" in den "else"-Zweig des ersten packst (was Du mit einem "else if" faktisch tust), dann wird die zweite Bedingung überhaupt nur dann geprüft, wenn die erste NICHT zutraf, beziehungsweise bei längeren Ketten aus "if (...) { ... } else if (...) { ... } else if (...) { ... }" wenn KEINE der vorangegangenen Bedingungen zutraf.
Es ist definitiv kein logisches (boolsches) Oder (or). Ganz plumpes Beispiel, wo es einen Unterschied gibt.
bool a = true;
bool b = true;
if (a) { do_a(); }
if (b) { do_b(); }
/* Sowohl do_a() als auch do_b() werden aufgerufen! */
Hingegen ...
bool a = true;
bool b = true;
if (a) { do_a(); }
else if (b) { do_b(); }
/* Nur do_a() wird aufgerufen, da die zweite
Bedingung sich im "else-Zweig" der ersten
befindet und daher nur geprüft wird, falls
die erste Bedingung NICHT zutraf! */
Ein "else if" macht quasi zur Voraussetzung, dass die zweite Bedingung überhaupt geprüft wird, dass bei der vorhergehenden Bedingung der bedingte Code nicht durchlaufen wurde.
Es ist letztlich eine weitere Bedingung ("if") im "else"-Zweig der vorangegangenen.
if (a)
{
do_a();
}
else if (b)
{
do_b();
}
... ist letzten Endes nur eine "schönere Schreibweise" für ...
if (a)
{
do_a();
}
else
{
if (b)
{
do_b();
}
}
Letztlich "sieht" der Compiler genau das selbe. Die zweite "if-Anweisung" befindet sich im "else-Zweig" der ersten "if-Anweisung". Wenn nur eine einzelne Anweisung folgt (in diesem Fall eben eine "if-Anweisung"), sind die geschweiften Klammern ja optional.
Ich könnte also auch schreiben ...
if (a)
do_a();
else if (b)
do_b();
... und das ist ja äquivalent (nur anderer Whitespace und Whitespace trägt ja in C keine Bedeutung) zu folgendem Code ...
if (a)
do_a();
else
if (b)
do_b();
Dann verstehst Du vielleicht, was passiert. ;-)
Nur falls "a" nicht zutrifft, prüfe "b" ...
... und falls das zutrifft, führe "do_b()" aus.
Du willst - bzw Dein Programm soll Tomaten kaufen. Aber mindestens fünf, damit jeder eine kriegt. Wenn bei Kauf von mindestens 25 Stück Tomaten im Sonderangebot sind, gibt es Tomatensuppe am Wochenende .. dafür müssen es aber mindestens 25 Tomaten sein (dann mußt Du natürlich die 5 einzelnen nicht mehr kaufen):
wenn ( ware=tomate ) - { tomatenzähler + 1 } wenn ( tomatenzähler >=25 Stück und tomatenpreis=sonderpreis ) - { 25 Stück kaufen } sonst, nur wenn außerdem auch ( tomatenzähler>=5 ) - { 5 Stück kaufen }
machst Du das unverschachtelt mit if . . . if . . . hast Du nachher 30 Tomaten. Das geht zwar zu verhindern mit Zusatzbedingung für die 5 Einzelnen (wenn nicht schon gekauft .. oder wenn nicht Sonderpreis zB). Ist aber überflüssig. Mit Verschachtelung wird die Bedingung gar nicht erst mehr geprüft .. der Programmfluß kann sie zeitsparend übergehen.
Beim zweiten Fall wird das zweite if nur überprüft, wenn das erste falsch ergeben hat.
Wenn du zum beispiel ein Objekt mit einer Reihe andere Objekte vergleichen willst, aber nur eins passt, ist das sinnvoll.
Wobei man dann eher switch-case nimmt.
Gerade "switch-case" funktioniert in vielen Sprachen nur mit einfachen Datentypen (z. B. int), nicht mit Objekten (z. B. String), da es in Maschinensprache in eine Jump-Table übersetzt wird, also eine Tabelle mit Werten und Sprungzielen (Adressen, auf die ein "branch"-Statement zeigt). Der Vergleich von Objekten läuft aber häufig (sofern man nicht lediglich die Referenzen/Pointer vergleicht) so, dass das Objekt eine "compare"-Methode aufruft. Das muss dann in Maschinensprache zu einem Unterprogrammaufruf ("call"-Statement) übersetzt werden. Damit fällt die Jump-Table flach. Daher funktionieren in vielen Sprachen "switch-case"-Statements nur mit primitiven Datentypen bzw. häufig auch nur mit numerischen Datentypen.
Ich denke, es wäre bescheuert, wenn es nicht auch mit Objektreferenzen geht.
Siehe enums oder Exemplarobjekte.
Ich habe hier versucht darüber eine Antwort zu geben. Das IF-ELSE Konstrukt wird bei Mehrfachselektion gerne um das "else if"-Konzept erweitert: http://www.santis-training.ch/java/pitfalls.php (Runterscrollen zu if/else und "else if")
Also ein ODER-Gied?
Oder ein " If-OR".......gg................