bedingte Anweisungen (Vergleichs- und logische Operatoren)

<-- zurck zur Startseite | <- eine Seite vor | eine Seite weiter ->

  1. der if-Block
  2. Vergleichsoperatoren
  3. logische Operatoren
  4. Prioritäten
  5. Übung
  6. Lösung

1. der if-Block

Bedingte Anweisungen sind in fast allen modernen Programmiersprachen extrem wichtige Bestandteile. Mit ihnen kann man, abhängig vom eingetretenen "Ereignis", unterschiedliche Programmblöcke, Funktionen etc. ablaufen lassen. Man denke nur an die Menüs in allen Anwendungsprogrammen!

Die einfachste bedingte Anweisung ist der if-Block. Syntax:

if (ausdruck) {
   // verschiedene Anweisungen

Zwischen die geschweiften Klammern kann beliebiger Programmcode geschrieben werden, aber wann genau wird dieser nun ausgeführt? Ganz einfach: sobald der Ausdruck (in den runden Klammern hinter if) true ergibt. Wir merken uns, dass if-Anweisungen boolesche Ausdrücke auswerten. Ergo wird der Teil innerhalb der if-Anweisung nicht ausgeführt, wenn der Ausdruck false ergibt.

Natürlich kann man einfache boolesche Variablen verwenden, um sie der if-Anweisung zu übergeben:

boolean testIt = true;
if (testIt) {
  // diese Anweisungen werden ausgef&#252;hrt, da testIt "true" ist
}

nach oben

2. Vergleichsoperatoren

Aber nicht nur boolesche Variablen liefern boolesche Werte (true und false), sondern auch eine Reihe von Operatoren! Die erste Kategorie von Operatoren, die boolesche Werte zurückliefern, sind Vergleichsoperatoren bzw. Gleichheitsoperatoren: wir kennen sie bereits aus der Mathematik (ist-gleich, größer, größer gleich, kleiner, kleiner gleich, usw.). Eine Auflistung der Vergleichsoperatoren in Java:

OperatorBedeutung
==gleich
!=ungleich
<kleiner als
>größer als
<=kleiner oder gleich
>=größer oder gleich
instanceofTypvergleich

Wie in der Mathematik muss sowohl links als auch rechts vom Vergleichs- bzw. Gleichheitsoperator ein Operand stehen. Die Verwendung ist eher banal: stimmt der Vergleich (wie in der Mathematik), wird "true" zurückgegeben, andernfalls "false".
Zu beachten ist folgendes: Die Gleichheit wird, wie auch in anderen Programmiersprachen mit == ausgedrückt und nicht mit =. Das einfache Gleichheitszeichen ist nämlich kein "ist-gleich" im mathematischen Sinne, sondern ein Zuweisungsoperator, z.B. für Variablen!
Der Operator instanceof ist eine Java-Spezialität und existiert so nicht in anderen Sprachen. Er prüft, ob der linke Operand eine Instanz der Klasse (oder einer Tochterklasse davon) ist, deren Name als rechter Operand angegeben wird, d.h. ob das Objekt auf der Klasse gebildet worden ist. Zunächst kümmern wir uns um ihn nicht weiter, wir werden auf ihn bei der objektorientierten Programmierung zurückkommen.
Sehen wir uns ein Beispiel an:

int a = 3;
if (a <= 3) {
   System.out.println("Genau, a sollte 3 nicht ueberschreiten!");
}

nach oben

3. logische Operatoren

Logische Operatoren erzeugen ebenfalls boolesche Rückgabewerte: sie verbinden mehrere boolesche Werte und bilden daraus einen neuen booleschen Wert. Die wichtigsten sind:

OperatorBedeutungWirkung
&&"und"ergibt "true", wenn sowohl die linke als auch die rechte Seite "true" ist
||"oder"ergibt "true", wenn entweder die linke oder die rechte oder beide Seiten "true" sind
!"nicht"ergibt "true", wenn der Ausdruck, vor dem er steht, "false" ist: "dreht den Wert um"

Der Nicht-Operator wird auch Negation genannt. Sehen wir uns nun ein Beispiel an:

int a = 4, b = 5;
if ((a < b) && !(a+b < 8)) {
   System.out.println("alle Bedingungen erfuellt!");
}

Die if-Anweisung wird ausgeführt: die linke Seite ergibt "true", da a wirklich kleiner ist als b. Sehen wir uns die rechte Seite an: a+b ergibt 9, 9 ist aber nicht kleiner als 8, also ergibt der Ausdruck in Klammern "false". Der wird aber durch die Negation gleich wieder umgedreht und wird somit "true". Also haben wir: TRUE && TRUE, d.h. sowohl die linke als auch die rechte Seite ist "true". Damit ist die Bedingung für das "und" erfüllt und der Gesamtausdruck ergibt true. Ergo wird der if-Block ausgeführt. Wäre nur eine der beiden Seiten "false" dann wäre auch der Gesamtausdruck "false" und die if-Anweisung würde übersprungen werden.
Weitere logische Operatoren mit geringerer Bedeutung sind:

OperatorBedeutungWirkung
^"exklusiv-oder"ergibt "true", wenn genau eine Seite "true" und die andere "false" ist, aber nicht beide "true" oder "false"
&"und"ohne short-circuit-evaluation, auch Zeichen für "bitweises und"
|"oder"ohne short-circuit-evaluation, auch Zeichen für "bitweises oder"

short-ciurcuit-evaluation ahmt in gewisser Weise das menschliche, logische Schließen nach: wenn in einem "und"-Ausdruck, wo beide Seiten "true" sein müssen, bereits die linke Seite "false" ist, dann muss ja der ganze Ausdruck "false" sein, egal was auf de rechten Seite steht, also kann ich mir Arbeit sparen und schon nach dem linken Ausdruck aufhören. Schreibe ich das "und" nicht mit &&, sondern mit &, dann werden aber trotzdem beide Teilausdrücke ausgewertet.
Ein kleines Beispiel für das "exklusiv-oder":

int a = 4, b = 5;
if ((a < b) ^ !(a+b < 8)) {
   System.out.println("alle Bedingungen erfuellt!");
}

Jetzt wird der if-Block übersprungen, obwohl die Zahlen dem obigen Beispiel gleichen. Allerdings darf jetzt nur genau eine Seite "true" ergeben: weder dürfen beide Seiten "false" sein, noch dürfen beide Seiten "true" sein. Letzteres ist aber hier der Fall, also wird übersprungen.
Daneben bietet Java wie C/C++ bitweise Operatoren, mit denen direkt auf die Binärdarstellung von numerischen Datentypen zugegriffen werden kann. Das bedeutet, sie interessiert nicht die Zahl in unserem dezimalen Zahlensystem, sondern interessiert sich für die binäre Darstellung auf Maschinenebene. Für uns im Moment nicht wichtig, verweise ich interessierte Mitstreiter auf externe Literatur.

nach oben

4. Prioritäten

Und um die Verwirrung komplett zu machen, gibt es eine Rangreihenfolge, welche Operatoren, wenn sie (ohne Klammern) nebeneinander stehen, zuerst ausgewertet werden. Die Tabellen hierzu sind schon fast eine Wissenschaft für sich, deswegen begnügen wir uns mit den wichtigsten. Die Reihenfolge der Priorität:

  1. (runde) Klammern
  2. das logische "nicht", Inkrement/Dekrement
  3. Multiplikation, Division, Modulo
  4. Addition, Subtraktion, String-Verkettung
  5. Vergleichsoperatoren (<, <=, >, >=, instanceof)
  6. Gleichheitsoperatoren (==, !=)
  7. logisches "exklusiv-oder"
  8. logisches "und"
  9. logisches "oder"
int a = 4, b = 5;
if (a < b && a+b > 9 || a+1 == b) {
   System.out.println("nur nicht verwirren lassen!");
}

Wenn wir zunächst die Vergleichsoperatoren auswerten, bekommen wir folgenden Ausdruck: TRUE && FALSE || TRUE. Da das logische "und" eine höhere Priorität hat, wird es zuerst ausgewertet: TRUE && FALSE ergibt FALSE, also verkürzt: FALSE || TRUE. Der Gesamtausdruck wird also true sein!

Übrigens geht Folgendes nicht:

int x=2;
if (0<x&<5) {
   System.out.println("Wert liegt zwischen 0 und 5");
}

Hier würde der Compiler wie der Mensch von links nach rechts lesen und wertet zuerst 0<x aus. Zurückgegeben wird ein boolescher Wert, der aber dann im nächsten Schritt nicht mehr mit 5 verglichen werden kann. Bei z.B. TRUE<5 bricht der Compiler mit einer Fehlermeldung ab. Man muss also in den sauren Apfel beißen und den Ausdruck als "x größer 0 und zugleich x kleiner 5" schreiben:

int x=2;
if ((x>0) && (x<5)) {
   System.out.println("Wert liegt zwischen 0 und 5");
}

Da alle diese Operatoren boolesche Werte zurückliefern, kann man mit ihnen auch den Wert boolescher Variablen setzen. Ein Beispiel:

int a = 4, b = 5;
boolean testIt = !(a+b < 8);

Und natürlich kann man sie auch den Rückgabewerte einer Funktion generieren lassen:

public static boolean testIt(int a, int b) {
  return !(a+b < 8);
}

nach oben

5. Übung

Bewerte folgende logische Ausdrucke, ob sie für a=3, b=5, c=7 "true" oder "false" ergeben (ohne ein Java-Programm zu Hilfe zu nehmen):

  1. (a == 3) && (c-b < a)
  2. (b%a > c-a) || !(a+a < c)
  3. (b >= a) && (c >= b) || (a+b < c)
  4. (b == 1) || !(a == 2)
  5. (a*a-c < a) ^ (b != 5)

nach oben

6. Lösung

  1. (3 == 3) && (7-5 < 3)
    true && true
    true
  2. (5%3 > 7-3) || !(3+3 < 7)
    (2 > 4) || !(6 < 7)
    false || !(true)
    false || false
    false
  3. (5 >= 3) && (7 >= 5) || (3+5 < 8)
    true && true || false
    true || false
    true
  4. (5 == 1) || !(3 == 2)
    false || !(false)
    false || true
    true
  5. (3*3-7 < 3) ^ (5 != 5)
    (9-7 < 3) ^ (5 != 5)
    true ^ false
    true

nach oben