Mit dem bisherigen Wissen, können wir unsere Programme immer nur sequentiell ablaufen lassen. Unsere Programme liefen also immer Zeile für Zeile ab. In diesem Teil wollen wir nun den sequentiellen Programmfluss brechen. C C++ C/C++ Kontrollstrukturen Verzweigungen Schleifen Sprünge if else for do while break continue Kontrollstrukturen - Verzweigungen Schleifen Sprünge if else for do while break continue Kapitel 11: Kontrollstrukturen

Mit dem bisherigen Wissen können Sie die Programme immer nur sequenziell ablaufen lassen, sie laufen also immer Zeile für Zeile ab. In diesem Kapitel wird nun der sequenzielle Programmfluss gebrochen.

Folgende drei Möglichkeiten haben Sie, um den sequenziellen Programmfluss zu ändern:

11.1. Verzweigungen mit if Bedingung            zurück  Ein Kapitel tiefer  zum Inhaltsverzeichnis

Die if-Bedingung hat folgende Syntax:

if(BEDINGUNG==wahr)
   {
      Anweisung1;
   }
Anweisung2;

Wenn die Bedingung zwischen den Klammern des if-Schlüsselwortes wahr (true) ist, wird Anweisung1 im Anweisungsblock ausgeführt. Anschließend wird das Programm bei Anweisung2, also nach dem Anweisungsblock, fortgesetzt. Ist die Bedingung unwahr (false), wird Anweisung1 nicht ausgeführt, und das Programm fährt sofort mit Anweisung2 fort.

11.1.1 Anweisungsblock
In einem Anweisungsblock werden Anweisungen (mindestens eine) zusammengefasst. Als Anweisungsblock gelten alle Anweisungen, die zwischen geschweiften Klammern ({}) stehen. Anweisungsblöcke lassen sich auch ineinander verschachteln. Es empfiehlt sich daher, auf eine saubere Strukturierung (d.h. entsprechendes Einrücken bei den Anweisungen eines Blocks) beim Erstellen eines Programms zu achten, um den Überblick zu bewahren.

Den Programmablauf der if-Bedingung können Sie sich schematisch folgendermaßen vorstellen (die Darstellung wird auch als Programmablaufplan bezeichnet):

Abbildung 11.1: Programmablaufplan zur if-Anweisung
Abbildung 11.1: Programmablaufplan zur if-Anweisung

Sehen Sie sich dazu das folgende Programmbeispiel an:

#include <stdio.h>

int main()
{
   unsigned int alter;

   printf("Wie alt sind Sie: ");
   scanf("%d", &alter);

   if(alter < 18)
      {
         printf("Sie sind noch nicht volljährig\n");
      }
    printf("Bye\n");
    return 0;
}

Das Programm fordert Sie auf, Ihr Alter einzugeben. In der Bedingung if(zahl < 18) wird überprüft, ob Sie jünger als 18 Jahre alt sind. Sind Sie jünger, wird die printf()-Anweisung im Anweisungsblock mit entsprechender Ausgabe bearbeitet. Wurde aber ein Wert eingegeben, der größer oder gleich 18 ist, wird nur die printf()-Anweisung hinter dem Anweisungsblock ausgeführt, die "Bye" ausgibt. Dieses Beispiel als Programmablaufplan:

Abbildung 11.2: Programmablaufplan zum Listing
Abbildung 11.2: Programmablaufplan zum Listing

Jetzt soll das Programm um einige if-Bedingungen erweitert werden:

#include <stdio.h>

int main()
{
   unsigned int alter;

   printf("Wie alt sind Sie: ");
   scanf("%d", &alter);

   if(alter < 18)
      {
         printf("Sie sind noch nicht volljährig\n");
      }
   if(alter > 18)
      {
         printf("Sie sind volljährig\n");
      }
   if(alter == 18)
      {
         printf("Den Führerschein schon bestanden?\n");
      }
    printf("Bye\n");
    return 0;
}

Es ist offensichtlich, wie das Programm vorgeht: Sie geben das Alter ein und mithilfe der einzelnen if-Bedingungen testet es, ob die eingegebene Zahl größer, kleiner oder gleich 18 ist. Bevor das Programm etwas genauer analysiert wird, sollten Sie sich eine Tabelle mit den bisher verwendeten Vergleichsoperatoren und ihrer jeweiligen Bedeutung ansehen.

Vergleichsoperator Bedeutung
a < b Wahr, wenn a kleiner als b
a <= b Wahr, wenn a kleiner oder gleich b
a > b Wahr, wenn a größer als b
a >= b Wahr, wenn a größer oder gleich b
a == b Wahr, wenn a gleich b
a != b Wahr, wenn a ungleich b

Tabelle 11.1: Übersicht zu Vergleichsoperatoren (Relationale Operatoren)

Zurück zum Programm. Die erste Anweisung

if(alter < 18) 

testet, ob die Zahl, die Sie eingegeben haben, kleiner als 18 ist. Ist die Bedingung wahr, springt das Programm unmittelbar in den für diese Bedingung geschriebenen Anweisungsblock, der in den geschweiften Klammern steht. Falls also die eingegebene Zahl kleiner als 18 ist, wird der Anweisungsblock

      {
         printf("Sie sind noch nicht volljährig\n");
      }

ausgeführt. Besteht der Anweisungsblock hinter der Kontrollstruktur lediglich aus einer einzigen Anweisung, so können die geschweiften Klammern auch weggelassen werden:

if(alter < 18)
   printf("Sie sind noch nicht volljährig\n");

Diese Schreibweise ist korrekt und wird auch häufig verwendet. Sie sollten sich jedoch klar machen, dass sie sehr leicht zur Fehlerquelle werden kann. Nämlich dann, wenn Sie eine weitere Anweisung hinzufügen wollen, die auch nur in dem Fall ausgeführt werden soll, wenn die if-Bedingung wahr ist, wie etwa im folgenden Beispiel:

if(alter < 18)
      printf("Sie sind noch nicht volljährig\n");
      printf("Sollte nur erscheinen, wenn (alter < 18)!\n");

Wenn - wie hier - dann die geschweiften Klammern vergessen werden, wird die zweite printf()-Anweisung immer ausgeführt, da die if-Bedingung im Wahr-Fall wirklich nur eine weitere Anweisung ausführt. Korrekt müsste es folgendermaßen aussehen:

if(alter < 18)
   {
      printf("Sie sind noch nicht volljährig\n");
      printf("Sollte nur erscheinen, wenn (alter < 18)!\n");
   }

Jetzt wird auch die zweite Anweisung nur ausgeführt, wenn die if-Bedingung wahr ist. Die nächsten beiden if-Bedingungen verhalten sich analog. Hiermit wird getestet, ob die eingegebene Zahl für das Alter kleiner bzw. gleich 18 ist. Sollte sich einer dieser Fälle als wahr herausstellen, so wird ebenfalls der jeweils zugehörige Anweisungsblock ausgeführt.



Achtung
 

Ein häufig gemachter Fehler ist if(alter=18).Hier wurde der Variablen alter der Wert 18 zugewiesen, und der Anweisungsblock wird ausgeführt. Dabei ist es jedoch egal, ob der Wert gleich 18 ist, denn alter wird jetzt der Wert 18 zugewiesen. Diese if-Abfrage ist also immer wahr. Der Fehler ist zudem schwer auffindbar, da die Syntax absolut korrekt ist, der Compiler also keine Fehlermeldung anzeigt. Oft verwendete und empfohlene Maßnahme ist es, die Überprüfung umzustellen: if (18 == alter) ist syntaktisch korrekt und bewirkt das Gleiche. Hiermit würde der Compiler sofort eine Fehlermeldung anzeigen, falls Sie versehentlich if (18 = alter) schreiben, da sich einer Zahl keine Variable zuordnen lässt. Diese Umstellungsmethode funktioniert nur bei ==-Vergleichen, nicht bei den anderen Operatoren.

11.2. Die Verzweigung mit else if            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Was ist, wenn die erste Bedingung im Listing zuvor wahr ist, d.h. die Zahl größer als 18 ist? Dann nimmt das Programm als nächsten Schritt dennoch die Überprüfung vor, ob die Zahl kleiner als 18 und gleich 18 ist. Das ist eigentlich nicht mehr notwendig. Sie können dies mit else if verbessern:

   else if(alter > 18)
      {
         printf("Sie sind volljährig\n");
      }
   else if(alter == 18)
      {
         printf("Den Führerschein schon bestanden?\n");
      }

Hier die Syntax dazu:

if(BEDINGUNG1==wahr)
   {
      Anweisung1;
   }
else if(BEDINGUNG2==wahr)
   {
      Anweisung2;
   }
Anweisung3;

Ist die Bedingung1 wahr, wird die Anweisung1 im Anweisungsblock ausgeführt, und die Kontrollstruktur ist fertig. Ist Bedingung1 nicht wahr, wird die Bedingung2 überprüft. Ist Bedingung2 wahr, wird Anweisung2 ausgeführt, und das Programm endet. Ist aber auch Bedingung 2 nicht wahr, wird die Anweisung 3 ausgeführt.

Der Programmablaufplan dazu:

Abbildung 11.3: Programmablaufplan if-else if
Abbildung 11.3: Programmablaufplan if-else if

Das Programmbeispiel sieht in der neuen Fassung so aus:

#include <stdio.h>

int main()
{
   unsigned int alter;

   printf("Wie alt sind Sie: ");
   scanf("%d", &alter);

   if(alter < 18)
      {
         printf("Sie sind noch nicht volljährig\n");
      }
   else if(alter > 18)
      {
         printf("Sie sind volljährig\n");
      }
   else if(alter == 18)
      {
         printf("Den Führerschein schon bestanden?\n");
      }
   printf("Bye\n");
   return 0;
}

11.3. Die Verzweigung mit else            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Eigentlich hätten Sie sich im vorangegangenen Programmbeispiel folgende Bedingung sparen können:

else if(alter == 18) 

Denn wenn die Variable alter nicht größer als 18 und auch nicht kleiner als 18 ist, kann diese nur noch gleich 18 sein. Um sich eine solche Bedingung zu ersparen, gibt es die else-Verzweigung, was soviel heißt wie Ansonsten nimm mich oder Andernfalls tue das Folgende:

Sie könnten also die Zeile else if(alter == 18) ersetzen durch:

   else
      {
         printf("Den Führerschein schon bestanden?\n");
      }

Die Syntax der if else-Verzweigung sieht folgendermaßen aus:

if(BEDINGUNG==wahr)
   {
      Anweisung1;
   }
else
   {
      Anweisung2;
   }

Sehen Sie sich hierzu auch den Programmablaufplan an:

Abbildung 11.4: Programmablaufplan mit else
Abbildung 11.4: Programmablaufplan mit else



Merke
 

else folgt immer einem vorausgehenden if oder else if.

Umgeschrieben sieht das Listing jetzt wie folgt aus:

#include <stdio.h>

int main()
{
   unsigned int alter;

   printf("Wie alt sind Sie: ");
   scanf("%d", &alter);

   if(alter < 18)
      {
         printf("Sie sind noch nicht volljährig\n");
      }
   else if(alter > 18)
      {
         printf("Sie sind volljährig\n");
      }
   else
      {
         printf("Den Führerschein schon bestanden?\n");
      }
   printf("Bye\n");
   return 0;
}

Jetzt haben Sie die einzelnen Bedingungen im Programm optimal gestellt. Wird z.B. für das Alter der Wert 16 eingegeben, führt das Programm den entsprechenden Anweisungsblock aus. Danach folgen keine weiteren Überprüfungen. Wird hingegen für das Alter der Wert 20 genannt, ersparen Sie sich wenigstens die letzte Überprüfung, ob das Alter gleich 18 ist, und entsprechender Anweisungsblock wird ausgeführt. Trifft keine dieser Bedingungen zu, wird der else-Anweisungsblock ausgeführt. Für das bessere Verständnis ein Programmablaufplan zu diesem Listing:

Abbildung 11.5: Programmablaufplan zum Listing
Abbildung 11.5: Programmablaufplan zum Listing

Ein häufig gemachter Fehler ist es, hinter eine Bedingungsanweisung ein Semikolon zu setzen:

   else if(alter > 18);   //Fehler (das Semikolon)
      {
         printf("Sie sind volljährig\n");
      }

Der Compiler wird Ihnen in solchen Fällen dahingehend eine Fehlermeldung ausgeben, dass else hier fehl am Platz ist. Denn einer else-Verzweigung muss immer ein if bzw. else if vorausgehen. Sie können probeweise im Listing hinter der else-Verzweigung ein Semikolon setzen. Das Programm wird dann immer ausgeben, dass die Variable gleich 18 ist. Dies wird zusätzlich ausgegeben, auch wenn eine der vorangegangenen Bedingungen bereits wahr gewesen ist.

Es ist auch möglich, mehrere Anweisungen bzw. Anweisungsblöcke ineinander zu verschachteln. Das heißt, eine Anweisung mit Anweisungsblock steht innerhalb einer Anweisung mit Anweisungsblock. Ein Beispiel:

#include <stdio.h>

int main()
{
   unsigned int alter;

   printf("Wie alt sind Sie: ");
   scanf("%d", &alter);

   if(alter <= 18)
      {
        if(alter == 18)
           {
              printf("Den Führerschein schon bestanden?\n");
           }
        else
           {
              printf("Sie sind noch nicht volljährig\n");
           }
      }
   else
      {
         printf("Sie sind volljährig\n");
      }
   printf("Bye\n");
   return 0;
}

Das Listing bewirkt das Gleiche wie schon das Beispiel zuvor. Mit der Anweisung

if(alter <= 18)

wird überprüft, ob alter kleiner oder gleich 18 ist. Sollte das der Fall sein, verzweigt das Programm weiter in den Anweisungsblock mit der Abfrage, ob alter gleich 18 ist. Wenn nicht, ist alter kleiner als 18.

Sollte die Zahl aber größer als 18 sein, geht es gleich zur else-Verzweigung.

Wie Sie die Anweisungsblöcke anordnen, bleibt Ihnen letztlich selbst überlassen. Sehen Sie sich dennoch einmal folgendes (Negativ-) Beispiel an:

#include <stdio.h>

int main()
{
   unsigned int alter;
   printf("Wie alt sind Sie: ");
   scanf("%d", &alter);

   if(alter <= 18){
   if(alter == 18){
   printf("Den Führerschein schon bestanden?\n");}
   else{
        printf("Sie sind noch nicht volljährig\n");
       }}
   else{printf("Sie sind volljährig\n");}
   printf("Bye\n");
   return 0;
}

Das Programm ist zwar nicht falsch, aber dennoch etwas unübersichtlich.

11.4. Der !-Operator (logischer Operator            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Den logischen !-Operator (NOT-Operator) haben Sie eben schon kennen gelernt. Dieser Operator wird oft falsch verstanden, weswegen ihm ein eigenes Kapitel gewidmet ist. Der !-Operator ist ein unärer Operator und kann einen Wert bzw. eine Bedingung negieren. Dies bedeutet, er kann aus "wahr" "falsch" machen und umgekehrt. Dazu ein Programmbeispiel :

#include <stdio.h>

int main()
{
   int checknummer;
   int code_key = 4711;

   printf("Bitte geben Sie Ihren Code-Schlüssel ein: ");
   scanf("%d", &checknummer);

   if( ! (checknummer == 4711) )
      {
         printf("Error - Falscher Code-Schlüssel \n");
      }
   else
      {
         printf("Success -  Login erfolgreich \n");
      }
   return 0;
}

Zur Erklärung der if-Bedingung im Programm:

if( !(checknummer == 4711) )

Hier wird der Ausdruck zwischen den Klammern geprüft. Das bedeutet, der !-Operator überprüft den Wert in der Klammer und gibt 1 (wahr) zurück, falls der Wert in der Klammer nicht 4711 ist. Ist der Wert aber gleich 4711, dann wird 0 (falsch) zurückgegeben, das Programm fährt mit der else-Verzweigung fort und gibt aus, dass Sie die richtige Zahl eingegeben haben.

Eine Tabelle mit den verschiedenen Verwendungsmöglichkeiten:

Anweisung == Anweisung
if(a == 1) gleich if(a)
if(a == 0) gleich if(!a)
if(a > b) gleich if(! (a <= b) )
if( (a-b) == 0) gleich if(! (a-b) )

Tabelle 11.2: Darstellung von Wahrheitswerten

Ein weiteres Programmbeispiel zur Verdeutlichung:

#include <stdio.h>

int main()
{
   int zahl1, zahl2;

   printf("Bitte Zahl 1 eingeben: ");
   scanf("%d", &zahl1);
   printf("Bitte Zahl 2 eingeben: ");
   scanf("%d", &zahl2);

   if(!zahl1)
      printf("Error: Der Wert ist gleich 0!! \n");
   else if(!zahl2)
      printf("Error: Der Wert ist gleich 0!! \n");
   else
      printf("%d/%d = %f \n", zahl1, zahl2, (float)zahl1/zahl2);
   return 0;
}

Sie vermeiden mit diesem Programm eine Division durch 0. Sollte also keine der beiden Zahlen dem Wert 0 entsprechen, wird mit (float)zahl1/zahl2 eine Division durchgeführt. Sie verwenden hier ein explizites Typencasting, damit der Wert nach dem Komma nicht einfach abgeschnitten wird.

11.5. Logisches UND (&&) - Logisches ODER (||)            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Sie haben sicher schon bemerkt, dass es in C viele Operatoren gibt. So ist die Sprache zwar unter Umständen schwerer lesbar, aber auch schneller, vielseitiger und effektiver programmierbar. Sobald Sie die Operatoren kennen gelernt haben, werden sie diese sehr zu schätzen wissen.

Mit dem logischen ODER-Operator (||) werden Operanden so miteinander verknüpft, dass der Ausdruck "wahr" zurückliefert, wenn mindestens einer der Operanden wahr ist.

if( (Bedingung1) || (Bedingung2) )
   /* mindestens eine der Bedingungen ist wahr */
else
   /* keine Bedingung ist wahr */

Sehen Sie sich dazu den Programmablaufplan des logischen ODER-Operators an:

Abbildung 11.6: Programmablaufplan des logischen ODER-Operators
Abbildung 11.6: Programmablaufplan des logischen ODER-Operators

Jetzt wird der Operator in dem Programm eingesetzt, dass Sie beim logischen NICHT-Operator zuvor verwendet haben:

#include <stdio.h>

int main()
{
   int zahl1, zahl2;

   printf("Bitte Zahl 1 eingeben: ");
   scanf("%d", &zahl1);
   printf("Bitte Zahl 2 eingeben: ");
   scanf("%d", &zahl2);

   if( (!zahl1) || (!zahl2) )
      printf("Error: Einer der Werte ist gleich 0!!! \n");
   else
      printf("%d/%d = %f \n", zahl1, zahl2, (float)zahl1/zahl2);
   return 0;
}

Zur if-Konstruktion des Programms:

if( (!zahl1) || (!zahl2) ) 

In Worten ausgedrückt sähe das etwa folgendermaßen aus: Ist der Wert zahl1 gleich 0 ODER der Wert zahl2 gleich 0, dann ist die Bedingung wahr, und Sie haben eine 0 eingegeben.

Sollte die erste Bedingung (!zahl1) schon wahr sein, so wird die zweite Bedingung (!zahl2) gar nicht mehr überprüft, dies können Sie auch am Programmablaufplan erkennen.

Analog verhält es sich mit dem logischen UND-Operator (&&). Das Ergebnis dieser verknüpften Operanden gibt nur dann "wahr" zurück, wenn alle Operanden wahr sind.

Der Programmablaufplan des logischen UND-Operators:

Abbildung 11.7: Programmablaufplan des logischen UND-Operators
Abbildung 11.7: Programmablaufplan des logischen UND-Operators

Wiederum zur Verdeutlichung ein Programmbeispiel:

#include <stdio.h>

int main()
{
   int zahl;
   printf("Geben Sie einen Wert zwischen 10 und 20 ein: ");
   scanf("%d", &zahl);

   if( (zahl >= 10) && (zahl <= 20) )
      printf("Danke für die Eingabe! \n");
   else
      printf("Falsche Eingabe! \n");
   return 0;
}

In der Zeile

if( (zahl >= 10) && (zahl <= 20) )

prüfen Sie, ob die eingegebene Zahl einen Wert zwischen 10 und 20 besitzt. In Worten: Ist es wahr, dass die Zahl größer oder gleich 10 ist UND die Zahl auch kleiner gleich 20, dann ist die Bedingung wahr.

Natürlich können Sie mit dem &&-Operator und dem ||-Operator weitere Bedingungen miteinander verknüpfen. Allerdings sollten Sie dabei die Lesbarkeit eines solchen Konstrukts im Auge behalten.

11.6. Bedingungsoperator ? :            zurück  Ein Kapitel tiefer  Ein Kapitel höher  zum Inhaltsverzeichnis

Der Bedingungsoperator ?: ist ein ternärer Operator (der einzige in ANSI C). Im Prinzip repräsentiert dieser Operator nichts anderes als eine Kurzform der if else-Anweisung. Hier die Syntax:

<BEDINGUNG> ? <ANWEISUNG 1> : <ANWEISUNG 2> 

Wenn die BEDINGUNG wahr ist, wird die ANWEISUNG1 ausgeführt. Ansonsten wird ANWEISUNG2 ausgeführt. Der Programmablaufplan ist identisch mit dem der if else-Anweisung.

Sie benötigen beispielsweise von zwei Zahlen den höheren Wert. Mit dem Bedingungsoperator ? : könnten Sie folgendermaßen arbeiten:

max = (a>b) ?a :b; 

Diese Schreibweise ist äquivalent zu der folgenden:

if(a > b)
   max=a;
else
   max=b;

Ein Listing:

#include <stdio.h>

int main()
{
   int a=5,b=10;
   int max;
   max = (a > b) ? a : b;
   printf("Der größte Wert ist %d \n", max);
   return 0;
}

Natürlich ist es auch hier möglich, die einzelnen Ausdrücke ineinander zu verschachteln:

#include <stdio.h>

int main()
{
   int a=8, b=3, c=76, big;
   printf("Die größte Zahl ist....");
   big = (a>b) ? ((a>c) ?a :c) : ((b>c) ?b :c);
   printf("..%d\n", big);
   return 0;
}

Auch hier kann bei mehrfacher Verschachtelung die Übersichtlichkeit und Nachvollziehbarkeit des Programms leiden. Hier wären if else-Anweisungen besser geeignet.

Sehen Sie sich folgende Codezeile näher an:

big = (a>b) ? ((a>c) ?a :c) : ((b>c) ?b :c); 

Bevor die Variable big einen Wert zugewiesen bekommt, werden zuerst folgende Bedingungen überprüft: Ist der Wert von a größer als der von b, wird überprüft, ob der Wert von a auch größer als der von c ist. Ist das der Fall, so ist a der größte Wert. Ist dies nicht der Fall, ist c der größte Wert. Sollte aber in der ersten Bedingung a nicht größer als b sein, so wird überprüft, ob b größer als c ist. Ist b größer als c, haben Sie den größten Wert gefunden. Ist b nicht größer als c, bleibt nur noch c als größte Zahl übrig.

Häufig wird der Bedingungsoperator auch wie folgt verwendet:

printf("Bitte geben Sie eine Zahl ein: ");
scanf("%d",&zahl);
printf("Die Zahl, die Sie eingegeben haben, ist ");
(zahl%2) ? printf("ungerade \n") : printf("gerade \n");

11.7. Fallunterscheidung: Die switch-Verzweigung            zurück  Ein Kapitel höher  zum Inhaltsverzeichnis

Was ist zu tun, wenn unterschiedliche Bedingungen mehrere verschiedene Zahlen beachten sollen? Sie könnten entsprechend viele if-Anweisungen verwenden. Aber warum so umständlich, wenn es einfacher geht? Für solche Aufgaben gibt es die Fallunterscheidung mit switch, was auf Deutsch soviel heißt wie Schalter. Die Syntax von switch sieht so aus:

switch(AUSDRUCK)
  {
     AUSDRUCK_1 : anweisung_1
     AUSDRUCK_2 : anweisung_2
     AUSDRUCK_3 : anweisung_3
     …
     AUSDRUCK_n : anweisung_n
  }

Der AUSDRUCK in den Klammern nach switch wird im darauf folgenden Anweisungsblock ausgewertet. Sollte der AUSDRUCK==AUSDRUCK_1 sein, so wird anweisung_1 ausgeführt. Sollte aber AUSDRUCK==AUSDRUCK_2 sein, so wird die anweisung_2 ausgeführt usw.

Hier ein Programm, welches Sie nach den Zahlen 1-5 abfragt:

#include <stdio.h>

int main()
{
   int a;
   printf("Bitte eine Zahl von 1-5 eingeben: ");
   scanf("%d", &a);

   switch(a)
      {
         case 1: printf("Das war eins \n");
                 break;
         case 2: printf("Das war zwei \n");
                 break;
         case 3: printf("Das war drei \n");
                 break;
         case 4: printf("Das war vier \n");
                 break;
         case 5: printf("Das war fünf \n");
                 break;
      }      /*Ende switch*/
   return 0;
}

Nach der Eingabe einer Zahl wird diese im Schalter ausgewertet mit:

switch(a) 

Die Auswertung steht wieder in einem Anweisungsblock in geschweiften Klammern. Zuerst wird

case 1: printf("Das war Eins \n");  

ausgewertet. case heißt auf Deutsch Fall. Zuerst wird geprüft, ob der Fall, der in switch(a) steht, zutrifft (also hier, ob a==1). Wenn ja, wird das Programm den entsprechenden Text ausgeben.

break;

Die break-Anweisung am Ende eines jeden Falls bedeutet: Ab hier springt das Programm aus dem Anweisungsblock heraus und setzt seine Ausführung nach dem switch-Anweisungsblock fort. In unserem Fall endet das Programm dann bereits. Wenn break nicht nach jedem Fall angegeben wird, wird der nächste Fall auch ausgegeben. Sehen Sie sich einen Programmablaufplan dazu an:

Abbildung 11.8: Programmablaufplan zur switch-Fallunterscheidung
Abbildung 11.8: Programmablaufplan zur switch-Fallunterscheidung

Das Weglassen von break kann aber durchaus gewollt sein. Dies hat den Vorteil, dass Sie in gewisser Weise auf mehrere Fälle gleichartig reagieren können. Das obige Programm wird leicht abgewandelt:

#include <stdio.h>

int main()
{
   int a;
   printf("Bitte eine Zahl von 1-5 eingeben: ");
   scanf("%d", &a);

   switch(a)
      {
         case 1: printf("Das war Eins oder...");
         case 2: printf("...Zwei \n");
                 break;
         case 3: printf("Das war Drei \n");
                 break;
         case 4: printf("Das war Vier...");
         case 5: printf("...oder Fünf \n");
                 break;
      }      /*Ende switch*/
   return 0;
}

Geben Sie in diesem Programm beispielsweise den Wert 4 für die Variable a ein, so trifft sowohl der Fall case 4 als auch case 5 zu, weil bei der Fallunterscheidung case 4 das break nach der printf()-Ausgabe weggelassen wurde. Ebenso würde sich das Programm verhalten, wenn Sie den Wert 1 eingegeben hätten.

11.7.1 default
Jetzt stellt sich die Frage, was geschieht, wenn Sie einen anderen Wert als 1 bis 5 eingeben. Das Programm einfach ohne eine Meldung zu beenden, ist unschön, denn es sollte auch bei falschen Werten eine Reaktion erfolgen. Dafür gibt es das Schlüsselwort default. Testen Sie es gleich in einem Programm:

#include <stdio.h>

int main()
{
   int a,b;
   char opera;
   printf("Grundrechnen \n");
   printf(" (zahl)(Operator)(zahl) ohne Leerzeichen \n");

   printf("Rechnung bitte eingeben : ");
   scanf("%d%c%d", &a, &opera, &b); /* Bsp.: 10+12 */

   switch(opera)
       {
           case '+': printf("%d + %d = %d \n",a ,b ,a+b);
                     break;
           case '-': printf("%d - %d = %d \n", a, b, a-b);
                     break;
           case '*': printf("%d * %d = %d \n", a, b, a*b);
                     break;
           case '/': printf("%d / %d = %d \n", a, b, a/b);
                     break;
           default: printf("%c? kein Rechenoperator \n", opera);
      }      /*Ende switch*/
 return 0;
}

Jetzt haben Sie auch gesehen, wie es möglich ist, jedes beliebige darstellbare ASCII-Zeichen mit case zu überprüfen. Einzelne Zeichen werden - wie beim Programm mit den Operatoren eben verwendet - zwischen einzelne Hochkommata gestellt.

Natürlich wäre es auch denkbar, statt

case '+': printf("%d + %d = %d \n", a, b, a+b);  

eben

case 43 : printf("%d + %d = %d \n", a, b, a+b);

zu verwenden, da ja das Zeichen '+' den dezimalen Wert 43 hat (siehe ASCII-Tabelle). Sie könnten auch die Oktalzahl 053 oder die Hexzahl 2B verwenden. Hier die Schreibweise für die Hexzahl von '+':

case 0x2B: printf("%d + %d = %d \n", a, b, a+b); 

Im Programm haben Sie gesehen, wie default verwendet wurde:

default: printf("'%c' ist kein Rechenoperator \n", opera); 

Falls Sie keine gültigen Rechenoperatoren eingegeben haben, bekommen Sie eine entsprechende Meldung. default bedeutet hier: Im Fall des Fehlens einer passenden case-Verzweigung, nimm immer das Folgende. Wenn also keine case Anweisung greift, dann wird der Code-Block nach default ausgeführt (man spricht oft vom so genannten Default-Verhalten, wenn der default-Block ausgeführt wird). Sie werden in einem späteren Kapitel noch sehen, dass sich die switch-Verzweigung hervorragend für den Aufbau eines einfachen Menüs in einer Konsolenanwendung eignet.

Weiter mit 11.8. Die while-Schleife             zum Inhaltsverzeichnis