1.06 Kontrollstrukturen Teil 2 – weitere Schleifen und switch-case

Weitere Schleifentypen

Bei den Zählschleifen, die wir bisher verwendet haben, wussten wir immer schon vor Beginn der Schleife, wie viele Wiederholungen stattfinden sollen. Das ist recht typisch für diese Schleifen. Wissen wir nicht, wie viele Wiederholungen durchlaufen werden sollen oder gibt es ein ganz anderes Kriterium als die Anzahl der Durchläufe, bieten sich while– oder auch do-while-Schleifen an.

Kopfgesteuerte Schleifen / while-Schleifen

Wir wandeln nun unser Programm zur Addition mehrerer Zahlen ab. Es soll nicht mehr am Anfang angegeben werden, wie viele Zahlen addiert werden. Stattdessen kann der Benutzer die Rechnung durch Eingabe einer 0 beenden. Daraufhin wird dann die Summe angezeigt.

Das können wir zum Beispiel so erreichen:

import java.util.Scanner;

public class WhileSchleife {

  public static void main(String[] args) {

        Scanner meinScanner = new Scanner(System.in);
        
        int summe;
        summe = 0;
        
        int geleseneZahl;
        geleseneZahl = 1;
        
        while(geleseneZahl != 0){
      	  System.out.print("Gib mir eine Zahl. Zum Beenden 0 eingeben: ");
      	  geleseneZahl = meinScanner.nextInt();
      	  summe = summe + geleseneZahl;
        }
        
        meinScanner.close();
        
        System.out.print("Summe: ");
        System.out.println(summe);
           

  }

}

Wir sehen hier unsere erste while-Schleife im Einsatz. Eine solche Schleife ist recht simpel aufgebaut. Wir müssen einfach in den runden Klammern hinter dem while die Bedingung zur Wiederholung der Schleife angeben. In diesem Fall soll die Schleife so lange wiederholt werden wie geleseneZahl nicht 0 ist.

Beachte, dass die Variable geleseneZahl schon vor der Schleife eingeführt und mit einem Startwert versehen wurde. Das ist ein Unterschied zur Zählvariablen in einer for-Schleife. Dadurch, dass die Variable vor der Schleife schon existiert, ist sie auch nach der Schleife noch vorhanden. Du kannst Dir zur Probe am Ende des Programms noch einmal geleseneZahl ausgeben lassen.

Zur Vertiefung hier der passende Clip:


Wiedergabe stellt eine Verbindung zu YouTube her.

Ein Detail möchte ich noch betonen: Wir mussten der Variablen einen Startwert geben, damit die Bedingung geleseneZahl != 0 überprüft werden kann. Wir haben wir den Startwert 1 gewählt. Es hätte auch jeder andere Wert mit Ausnahme von 0 sein dürfen.

Dieses mehr oder weniger künstliche Setzen eines Startwertes ist aber nicht besonders elegant. Geschickter als eine while-Schleife ist in diesem Fall daher eine do-while-Schleife.

Fußgesteuerte Schleifen / do-while-Schleifen

Sehen wir uns eine Umsetzung des Programms mit einer do-while-Schleife an:

import java.util.Scanner;

public class DoWhileSchleife {

  public static void main(String[] args) {

        Scanner meinScanner = new Scanner(System.in);
        
        int summe;
        summe = 0;
        
        int geleseneZahl;
        
        do{
      	  System.out.print("Gib mir eine Zahl. Zum Beenden 0 eingeben: ");
      	  geleseneZahl = meinScanner.nextInt();
      	  summe = summe + geleseneZahl;
        }while(geleseneZahl != 0);
        
        meinScanner.close();
        
        System.out.print("Summe: ");
        System.out.println(summe);
           

  }

}

Wie Du siehst, müssen wir hier der Variablen geleseneZahl vor der Schleife keinen Wert zuordnen. Der Grund ist, dass hier erst nach Durchlauf der Schleife die Bedingung geleseneZahl != 0 überprüft wird. Zu diesem Zeitpunkt hat geleseneZahl ja schon durch die Anweisung geleseneZahl = meinScanner.nextInt(); einen Wert erhalten.

Die Tatsache, dass die Bedingung erst nach der Schleife überprüft wird, hat übrigens den Effekt, dass die Schleife immer mindestens einmal durchlaufen wird. Bei einer while– oder for-Schleife kann es vorkommen, dass sie komplett übersprungen werden, wenn die Bedingung von Anfang an nicht erfüllt ist.

Hier der Clip zu den do-while-Schleifen:


Wiedergabe stellt eine Verbindung zu YouTube her.

Fallunterscheidungen mit switch-case-Anweisungen

Wir kennen bereits if-Abfragen als eine Möglichkeit der Fallunterscheidung. Bei if-Abfragen kann man überprüfen, ob eine Bedingung erfüllt ist oder nicht. Je nachdem, welcher Fall vorliegt, erfolgen dann andere Anweisungen. Bildlich gesprochen, stellt eine if-Abfrage also eine Weggabelung mit zwei möglichen Wegen dar.

Oft kommt es aber auch vor, dass mehr als nur zwei Fälle vorliegen können. In diesen Situationen kann man häufig eine switch-Anweisung verwenden. Schauen wir uns ein kleines Beispiel an:

public class SwitchBeispiel {

  public static void main(String[] args) {

    // Angabe Note
    int meineNote;
    meineNote = 2;
    
    
    // Übersetzung der Note		
    switch(meineNote){

    case 1:
      System.out.print("sehr ");

    case 2:
      System.out.print("gut");
      break;

    case 3:
      System.out.print("befriedigend");
      break;

    case 4:
      System.out.print("ausreichend");
      break;

    case 5:
      System.out.print("mangelhaft");
      break;

    case 6:
      System.out.println("ungenügend");
      System.out.println("Das sieht böse aus!");
      break;

    default:
      System.out.println("ungütliger Wert bei der Note");
      
    }
      
  }

}

Dieses Programm gibt mittels einer Fallunterscheidung die Bezeichnung der in meineNote gespeicherten Schulnote aus.

Eingeleitet wird diese Fallunterscheidung durch switch(meineNote). In der Klammer muss hier also die Variable stehen von deren Wert abhängt, welcher Fall – oder englisch „case“ – vorliegt. Entsprechend springt das Programm danach zu dem passenden Fall und führt die Anweisungen aus, die dort angegeben sind. Dabei werden alle Anweisung bis zum nächsten break; ausgeführt. Hat also meineNote den Wert 1, dann wird „sehr gut“ ausgegeben und nicht nur „sehr“.

Sollte keiner der angegebenen Fälle zum Wert von meineNote passen, springt das Programm zu default. Dies ist gewissermaßen das Auffangbecken für alle übrigen Fälle, die nicht explizit behandelt werden. Der default-Teil darf aber auch weggelassen werden.

Die Variable zur Fallunterscheidung darf vom Typ char, byte, short, int oder auch String sein. Sehen wir uns zum Abschluss eine Erweiterung des Programms von oben an, in der eine Variable vom Typ char verwendet wird:

public class SwitchBeispiel {

  public static void main(String[] args) {

    // Angabe Note
    int meineNote;
    meineNote = 2;
    
    // Angabe Tendenz
    char meineTendenz;
    meineTendenz = '+';
    /* Bei keiner Tendenz muss ' '
     * eingegeben werden.
     */
    
    // Übersetzung der Note		
    switch(meineNote){

    case 1:
      System.out.print("sehr ");

    case 2:
      System.out.print("gut");
      break;

    case 3:
      System.out.print("befriedigend");
      break;

    case 4:
      System.out.print("ausreichend");
      break;

    case 5:
      System.out.print("mangelhaft");
      break;

    case 6:
      System.out.println("ungenügend");
      System.out.println("Das sieht böse aus!");
      break;

    default:
      System.out.println("ungütliger Wert bei der Note");
      
    }
    
    // Übersetzung der Tendenz
    switch(meineTendenz){
    
    case '+':
      System.out.println(" plus");
      break;
    
    case '-':
      System.out.println(" minus");
      break;
      
    case ' ':
      System.out.println();
      break;
      
    default:
      System.out.println(" ungültiger Wert bei der Tendenz");
      
    }
    

  }

}

Auch zu diesem Abschnitt gibt einen Begleitclip 😉


Wiedergabe stellt eine Verbindung zu YouTube her.

VERTIEFUNG: break und continue

In den Vertiefungen findest Du Zusatzwissen, das ein erfahrener Programmierer haben sollte, für einen Einsteiger aber noch nicht allzu wichtig ist. Du kannst also entscheiden, ob Du es Dir jetzt schon ansiehst oder später darauf zurückkommst.

Mit break und continue kannst Du Sprünge innerhalb Deines Programms erreichen. Solche Sprunganweisungen werden allerdings sehr kritisch gesehen. In der Literatur wird oft von ihnen abgeraten und schon 1968 hat Dijkstra vor Sprunganweisungen (allerdings mit GoTo) gewarnt. Es ist vielleicht ganz amüsant, dass genau so eine GoTo-Anweisung im Jahr 2014 zu Apples berühmten GoTo-Fail sorgte.

Mit break kannst Du jederzeit eine switch-, while, do-while– oder auch for-Anweisung unterbrechen. Genauer gesagt, wird die Anweisung, in der das break steht unterbrochen:

import java.util.Scanner;

public class WhileSchleife {

  public static void main(String[] args) {

    Scanner meinScanner = new Scanner(System.in);

    int summe;
    summe = 0;

    int geleseneZahl;

    do{
      System.out.print("Gib mir eine Zahl. Zum Beenden 0 eingeben: ");
      geleseneZahl = meinScanner.nextInt();
      if (geleseneZahl == 0){
        break; // Verlassen der Schleife
      }
      summe = summe + geleseneZahl;
    }while(true);

    meinScanner.close();

    System.out.print("Summe: ");
    System.out.println(summe);


  }

}

Eigentlich liegt hier eine Endlosschleife vor. Nur durch das break gelingt der Ausstieg. Wie Du aber auch direkt sehen solltest, hätte man das Programm ohne Probleme auch ohne break erstellen können – weiter oben haben wir das ja gemacht 😉

Mit continue kannst Du den aktuellen Schleifendurchlauf einer while, do-while– oder auch for-Schleife überspringen. Die Schleife wird dann aber mit dem folgenden Durchlauf (sofern es noch einen gibt) fortgesetzt:

public class Zaehlschleife {

  public static void main(String[] args) {

    for (int zaehler = 1; zaehler <= 10; zaehler = zaehler + 1){

      if (zaehler%3==0){
        continue;
      }
      
      System.out.println(zaehler);

    }

  }

}

Hier werden alle ganzen Zahlen von 1 bis 10 ausgegeben, die nicht durch 3 teilbar sind. Anders ausgedrückt: Die durch 3 teilbaren Zahlen werden übersprungen.

Um es nochmal zu betonen: Diese Anweisungen sind kritisch zu betrachten. Aber falls sie Dir mal irgendwo begegnen, weißt Du nun, was sie bedeuten.