11.1.6 Mehrfachverzweigung

 

Schachtelung von mehreren if-Anweisungen Wie die letzten Hausaufgaben schon gezeigt haben, kann es vorkommen, dass man in einem Programmfluss an eine Stelle kommt, an der mehrerer Alternativen angeboten werden sollen. Hat eine solche Verzweigung nur zwei Optionen, löst man das Problem, wie wir es gelernt haben,  mit einer if-Anweisung. Möchte man bei einer Verzweigung aber mehr als 2 Möglichkeiten anbieten, so muss man, von unserem jetzigen Kenntnisstand ausgehend, die  Mehrfachverzweigung mit einer mehr oder weniger komplizierten Schachtelung von if-Anweisungen realisieren. Eine if-Schachtelung für  4 Optionen hat in Java z.B. folgende Gestalt:
.....
if(Bedingung 1){
  //Anweisungsteil für die Option 1
}
else {
  if (Bedingung 2){
    //Anweisungsteil für die Option 2
  }
  else {
    if (Bedingung 3){
      //Anweisungsteil für Option 3
    }
    else {
      //Anweisungsteil für die Option 4
    }
  }
}
....

 

Reihung von if-Anweisungen Mit wachsender Optionenanzahl wird das Programm immer unübersichtlicher und anfälliger für Fehler. Überschaubarer wird das Programm, wenn man auf die else-Anweisungen verzichtet. Unser Programm hat dann folgende Gestalt:
.....
if(Bedingung 1) {
   //Anweisungsteil für Option 1
}
if(Bedingung 2) {
   //Anweisungsteil für Option 2
}
if(Bedingung 3) {
   //Anweisungsteil für Option 3
}
if(Bedingung 4) {
   //Anweisungsteil für Option 4
}
....

Die gewonnene Übersichtlichkeit erkauft man sich allerdings mit einem Nachteil. Er besteht darin, dass jede if-Anweisung ausgewertet werden muss, gleich ob eine vorausgegangene if-Anweisung schon "erfolgreich" war.

switsch ..
int selektor;
selektor = .....//Initialisierung des Selektors

switch (selektor) {
   case 1  : //Anweisungen Option 1;
     break;
   case 2  : //Anweisungen Option 2;
     break;
   case 3  : //Anweisungen Option 3;
     break;
   case 4  : //Anweisungen Option 4;
     break;
   default ://was sonst passiert
}

Zur mehrseitigen Auswahl dient ein sog. Selektor, den wir der Einfachheit halber auch Selektor nennen. Er muss von einfachem Datentyp sein. wie
char, byte, short oder int. Wir haben den "Typ int" gewählt. Das reservierte Wort "switch" leitet die Selektion ein und die case-Anweisungen unterscheiden die verschiedenen Optionen. Hat der Selektor den Wert 3, so werden die Anweisungen der Option 3, also der Fall (=case) für den Selektorwert 3 ausgewertet. Um die Rolle des "break" kennen zu lernen, wollen wir uns ein Proramm ohne "breaks"  anschauen.
Die Rolle des break

Download:
Noten.java

 

Das Programm Noten fragt den Bediener nach der Eingabe einer Note in Form einer ganzen Zahl von 1 bis 6 und das Programm gibt die Note so aus, wie sie in einem Zeugnis erscheinen würde.
import info1.*;
public class Noten {
   public static void main(String[] args){
      System.out.print("Noteneingabe 1..6: ");
      int selektor = Console.in.readInt();
      switch (selektor){
	case 1: System.out.println("sehr gut");
	case 2: System.out.println("gut");
	case 3: System.out.println("befriedigend");
	case 4:	System.out.println("ausreichend");
	case 5: System.out.println("mangelhaft");
	case 6: System.out.println("ungenügend");
	default: System.out.println("Falsche Eingabe");
      }
   }
}

Java liefert bei der Eingabe von 3 und 5 die nachfolgenden Ausgaben:

Noteneingabe 1..6: 3
befriedigend
ausreichend
mangelhaft
ungenügend
Falsche Eingabe

bzw

Noteneingabe 1..6: 5
mangelhaft
ungenügend
Falsche Eingabe

Diese Ausgaben sind so zu erklären: Betrachten wir den Aufbau der swich-Anweisung genauer:

switch (s){
  case s1: Anweisung(1);
           Anweisung(2);
           ......;
	   Anweisung(m);
  case s2: Anweisung(m+1);
           Anweisung(m+2);
           ......;
           Anweisung(n);
  ...........
  case sk: Anweisung(n+1);
           Anweisung(n+2);
           .......;
           Anweisung(p);
  default: ...;
           ...;
           Anweisung(letzte);
}    

Die rot-markierten Klammern legen den switch-Block fest. Die case <..> sind Marken (Labels). Hat der Selektor s etwa den Wert <swert2>, so springt das Programm an die Marke case <swert2> und führt alle(!) Anweisungen im switch-Block aus. Die mit case bezeichneten Stellen im Programm sind also keine Verzweiger sondern lediglich Einstiegsmarkierer. Damit ist aber die Funktionalität einer Mehrfachverzweigung nicht gegeben. Die schafft man erst, wenn man den switch-Block durch einen Sprung wieder verlässt. Mit den breaks realisiert man nun genau diese Sprünge.

switch (s){
  case s1: Anweisung(1);
           Anweisung(2);
           ......;
	   Anweisung(m);
           break;
  case s2: Anweisung(m+1);
           Anweisung(m+2);
           ......;
           Anweisung(n);
           break; //Sprung aus dem Block
  ...........
  case sk: Anweisung(n+1);
           Anweisung(n+2);
           ........;
           Anweisung(p);
           break;
  default: ...;
           ...;
           Anweisung(letzte);
} 
Das Notenprogramm mit break

Download:
Notena.java

 

import info1.*;
public class Noten2 {
   public static void main(String[] args) {
      System.out.print("Noteneingabe 1..6: ");
      int selektor = Console.in.readInt();
      switch (selektor){
	case 1: System.out.println("sehr gut");break;
	case 2: System.out.println("gut");break;
	case 3: System.out.println("befriedigend");break;
	case 4:	System.out.println("ausreichend");break;
	case 5: System.out.println("mangelhaft");break;
	case 6: System.out.println("ungenügend");break;
	default: System.out.println("Falsche Eingabe");break;
       }
   }
}
Noteneingabe 1..6: 4
ausreichend
Process Exit.

 

Struktogramm

 

Noch ein Unterschied Ausdrücklich sei gesagt, dass nicht jede verschachtelte if-Anweisung in eine case-Anweisung übersetzt werden kann. Bei einer if-Anweisung wird nach einem booleschen Ausdruck selektiert, während bei einer case-Anweisung nur Werte der genannten Datentypen char, byte, short und int zur Selektion in Frage kommen. Das macht wieder den Einsatz einer if-Anweisung in vielem flexibler.

 

zu den Übungen  
zur Startseite www.pohlig.de (C)MPohlig 2002