Fallunterscheidung

Aus EINI
Wechseln zu: Navigation, Suche

Eine Fallunterscheidung ist eine häufig in Programmiersprachen implementierte Kontrollstruktur. Sie dient dazu, das Notieren von verschiedenen bedingten Anweisungen zu erleichtern. Dabei springt der Programmfluss vom Kopf der Fallunterscheidung zu einem spezifizierten Fall und setzt von da an die Ausführung fort.

In Java wird eine Fallunterscheidung durch das Schlüsselwort switch für den Kopf der Fallunterscheidung und case für die einzelnen Fälle deklariert. Da ein Fall nur eine Sprungmarke für den Programmfluss ist und keine sonstige Programmflusskontrolle vorgenommen wird, ist es speziell in diesen sogenannten switch-case-Anweisungsblöcken notwendig, mit der break-Anweisung manuell aus der Fallunterscheidung herauszuspringen, wenn man einen Fall abgearbeitet hat.

Syntaxdiagramm

Switch statement.png

(Aktuell noch teilweise fehlerhaft)

Verwendung

Fallunterscheidungen werden verwendet, wenn man mehrere fest definierbare Fälle überprüfen möchte, anstatt eine Verschachtelung von bedingten Anweisungen zu erstellen.

Das Wichtigste dabei ist, dass nur Konstanten als Fälle verwendet werden können. Zwei Variablen können also nicht miteinander verglichen werden. Da die eintretbaren Fälle diskret voneinander zu unterscheiden sein müssen, sind nur byte, char, short, int, String und Aufzählungskonstanten erlaubt. Man kann also keine Fallunterscheidungen für die Datentypen long, float und double verwenden.

Kopf

Der Kopf besteht aus dem Schlüsselwort switch, gefolgt von einem in Klammern notierten Term, über den die Fallunterscheidung getroffen werden soll.

switch(x){
   // Rumpf
}

Rumpf

Der Rumpf einer Fallunterscheidung wird durch einen Block eingeleitet. Im Rumpf können die einzelnen Fälle mit einer Sprungmarke markiert werden. Diese geschieht durch das Schlüsselwort case, gefolgt von einem konstanten Wert, der für den entsprechenden Fall steht, und einem Doppelpunkt.

switch(x){
    case 1: //...
    case 2: //...
}

Zusätzlich kann durch das Schlüsselwort default ein Standardfall deklariert werden, der ausgeführt werden soll, wenn kein anderer Fall passt. Dieser wird entsprechend meistens am Ende der Fallunterscheidung notiert:

switch(x){
    case 1: //...
    case 2: //...
    default: //...
}

break

Problematik

Da die einzelnen case- und default-Schlüsselwörter nur Sprungmarken repräsentieren und keine Kontrollstruktur aufbauen, würde der Programmfluss nach Abarbeiten eines Falls in die nächste Zeile wandern und, ungeachtet der Sprungmarke oder des eingetretenen Falls, weiterarbeiten:

switch(x){
    case 1: i++;
    case 2: i++;
    default: i++;
}

Hier würde also im Fall von x ist 1 der Wert von i dreimal, im Fall von x ist 2 der Wert von i zweimal und in allen anderen Fällen der Wert von i einmal erhöht werden. Dies ist in den meisten Fällen jedoch nicht gewünscht.

Lösung

Am Ende jeder Fallbehandlung bzw. vor der Sprungmarke eines nächsten Falles muss eine Anweisung mit dem Schlüsselwort break verwendet werden, um aus dem Rumpfblock der Fallunterscheidung herauszuspringen:

switch(wochentag){
    case 1: System.out.println("Montag");
            break;
    case 2: System.out.println("Dienstag");
            break;
    case 3: System.out.println("Mittwoch");
            break;
    case 4: System.out.println("Donnerstag");
            break;
    case 5: System.out.println("Freitag");
            break;
    case 6: System.out.println("Samstag");
            break;
    case 7: System.out.println("Sonntag");
            break;
    default: System.out.println("Kein Wochentag");
}

Die break-Anweisungen sorgen hier dafür, dass immer nur eine Anweisung ausgeführt wird, anstatt die Liste vom zutreffenden Fall bis zum Ende durchzulaufen.


Natürlich kann man sich diese Eigenschaft auch zunutze machen, um mehrere Fälle mit der gleichen Routine zu behandeln:

switch(monat){
    case 1: case 2: case 3: System.out.println("Erstes Quartal");
            break;
    case 4: case 5: case 6: System.out.println("Zweites Quartal");
            break;
    case 7: case 8: case 9: System.out.println("Drittes Quartal");
            break;
    case 10: case 11: case 12: System.out.println("Viertes Quartal");
            break;
    default: System.out.println("Kein Monat");
}

Hier werden jeweils drei Fälle mit der gleichen Ausgabe behandelt, indem drei Sprungmarken die gleiche Codezeile markieren.

Beispiel

int x;
int i = 0;
[...]
switch(x){
    case 2: i+=1;
    case 3: i+=1;
            break;
    case 4: i+=1;
            break;
    default: i=10; 
}

Wenn man davon ausgeht, dass die Variable i den Wert 0 bis zur Fallunterscheidung behält, wird, wenn x den Wert 2 hat, der Wert der Variablen i zweimal um 1 erhöht, da am Ende der Fallbehandlung case 2 kein break steht. Wenn sie hingegen den Wert 3 oder 4 hat, wird diese Anweisung jeweils nur einmal ausgeführt. Ist der Wert von x weder 2, 3 noch 4, so erhält i den Wert 10.

Verwendete Schlüsselwörter

  • switch
  • case
  • break