C++ Kurs

if-Verzweigung

Die Themen:

Syntax
Auszuführende Anweisungen
Mehrere Bedingungen
Bedingungsoperator und goto
Beispiel und Übung

Syntax

Die if-Verzweigung wird immer dann eingesetzt, wenn in Abhängigkeit von Bedingungen verschiedene Anweisungen auszuführen sind. Sie hat folgende allgemeine Syntax:

if (Ausdruck)
   Anweisung1 // IF-Zweig
else
   Anweisung2 // ELSE-Zweig

Ausdruck kann ein beliebiger C++ Ausdruck sein, der entweder ein ganzzahliges oder ein boolsches Ergebnis liefert. Der Ausdruck muss immer in runden Klammern stehen. In der Regel wird hier ein Vergleichs- oder Logikausdruck stehen.

Ergibt die Auswertung des Ausdrucks true (oder einen Wert ungleich 0), so wird die Anweisung Anweisung1 ausgeführt. In allen anderen Fällen wird die Anweisung Anweisung2 ausgeführt.


// Ausdruck mit logischem Vergleich
if (var == 10)      // Falls var gleich 10
   var = 0;         // var auf 0 setzen
else                // sonst
   var++;           // var inkrementieren

//Ausdruck mit ganzzahligem Vergleich
if (var)            // Falls var ungleich 0 (=true!)
   cout << "ungleich Null";
else                // sonst
   cout << "gleich Null";

Nach dem Ausdruck der IF-Abfrage darf kein Semikolon stehen. Wird hier ein Semikolon gesetzt so gilt dies als leere Anweisung, d.h. bei erfüllter Bedingung wird einfach nichts ausgeführt!

Auszuführende Anweisungen

Standardmäßig folgt auf ein if oder else nur eine Anweisung, so wie im vorherigen Beispiel dargestellt. Sollen mehrere Anweisung in Abhängigkeit von einer Bedingung ausgeführt werden, so sind die Anweisungen in einen Block {...} einzuschließen. Achten Sie dabei aber auf eine saubere Formatierung, damit das Programm gut lesbar bleibt.


if (var == 10)
{
   var = 0;
   cout << "var auf 0 gesetzt";
}
else
{
   var++;
   cout << "var jetzt:" << var;
}
cout << endl;

Außerdem ist der else-Zweig optional. Ist er nicht vorhanden und die Auswertung des Ausdrucks ergibt false, so wird mit der nächsten Anweisung nach dem if-Zweig fortgefahren. Im nachfolgenden Beispiel wird die Variable var nur dann dekrementiert, wenn ihr Inhalt ungleich 0 (entspricht true) ist.


if (var != 0)
{
   var--;
   cout << "var dekrementiert.";
}
cout << "var jetzt:" << var << endl;

Innerhalb eines if- oder else-Zweigs sind alle C++ Anweisungen zugelassen. So können in einem Zweig weitere if-Anweisungen folgen oder auch Variablen definiert werden.  Diese Variablen sind dann nur innerhalb des Zweigs gültig und belegen auch nur für diese Zeit Speicherplatz.


if (var > 0)
{
   short temp = var % 5;
   if (temp)                // falls temp ungleich 0
   {
      ...                   // Führe beliebige Anweisungen aus
   }
}
cout << "var jetzt:" << var << endl;

Sehen Sie sich einmal die beiden folgenden if-Anweisungen an:

if (var == 10)
    ....

if (var = 10)
    ....

Beide Anweisungen sind syntaktisch richtig! Im ersten Fall wird die Variable var mit dem Wert 10 verglichen und in Abhängigkeit davon, werden weitere Anweisungen ausgeführt. Im zweiten Fall wird der Variablen var der Wert 10 zugewiesen und das Ergebnis der Zuweisung ausgewertet. Und da var danach ungleich 0 (und somit true) ist, werden die Anweisungen im if-Zweig immer ausgeführt.

Mehrere Bedingungen

Bisher enthielten die if-Anweisungen immer nur eine Bedingung. Jedoch können auch mehrere Bedingung in einer if-Anweisung abgefragt werden Die Bedingungen sind dann mit logischer Operatoren zu verbinden. Das nachfolgende Beispiel zeigt, wie Sie eine if-Anweisung aufbauen die mehrere Bedingungen besitzt. Beachten Sie, dass die einzelnen Bedingungen in Klammern stehen und der gesamte if-Ausdruck nochmals geklammert ist.


// Hier müssen beide Bedingungen erfüllt sein
if ((var == 10) && (count != 0))
   ....

// Hier genügt es, wenn eine Bedingung erfüllt ist
if ((var == 10) || (count != 0))
   ....

Die Klammern um die einzelnen Bedingungen sind zwar nicht vorgeschrieben, jedoch sollten Sie sich an diese Vorgehensweise halten. Sie erleichtert den Überblick über die einzelnen Bedingungen und außerdem erleben Sie keine bösen Überraschungen in Bezug auf die Reihenfolge der Auswertung der einzelnen Operatoren. Oder wissen Sie noch, ob der GLEICH-Operator (==) vor dem UND-Operator (&&)ausgewertet wird oder umgekehrt?

Und noch ein Hinweis: die Anzahl der Bedingungen in einer if-Anweisung ist zwar nicht begrenzt, jedoch leidet die Übersichtlichkeit erheblich wenn sehr viele Bedingungen in einer if-Anweisung verarbeitet werden.

Die Anweisung

if (Ausdruck1) & (Ausdruck2)

ist syntaktisch richtig und erzeugt somit auch keinen Fehler beim Übersetzen des Programms. Hier werden die beiden Ausdrücke aber bitweise verundet und nicht logisch (was vermutlich erfolgen sollte).

Bedingungsoperator und goto

Eine etwas abgewandelte Form der if-Anweisung stellt der Bedingungsoperator dar, der folgende Syntax besitzt:

erg = (Ausdruck1) ? Ausdruck2 : Ausdruck3;

Liefert die Auswertung des Ausdrucks Ausdruck1 als Ergebnis true, so wird Ausdruck2 berechnet und das Ergebnis der Variablen erg zugewiesen. Liefert Ausdruck1 dagegen false, wird das Ergebnis von Ausdruck3 der Variablen erg zugewiesen. Im Beispiel sehen Sie, wie mithilfe dieser Anweisung der Absolutbetrag einer Variablen 'berechnet' werden kann. Außerdem ist ein etwas unkonventionelleres Beispiel aufgeführt, das je nach Zustand der Variablen light entweder den Text Das Licht ist an oder den Text Das Licht ist aus ausgibt.


// Absolutbetrag von var1 in var2 ablegen
var2 = (var1>0) ? var1 : -var1;
// Alternative Schreibweise:
//   if (var1>0)
//        var2 = var1;
//   else
//      var2 = -var1;


// Weiteres (unkonventionelles) Beispiel:
cout << "Das Licht ist " << ((light)? "an" : "aus") << endl;

Nur der Vollständigkeit halber sei an dieser Stelle noch erwähnt, dass C++ auch eine goto-Anweisung kennt. Sie hat folgende Syntax:

if (...)          // Falls Bedingung erfüllt
   goto label;    // Sprung nach label
...
label:            // Das Sprungziel
...

Das Sprungziel kann ein beliebiger, eindeutiger Namen sein und muss mit einem Doppelpunkt abgeschlossen werden. Für die Position des Sprungziels gibt es eine Reihe von Einschränkungen, die wir uns hier aber nicht ansehen wollen. In einem 'sauberen' Programm kommt man in der Regel ohne goto aus. Wie die goto-Anweisung eingesetzt wird, das können Sie sich im nachfolgenden Beispiel noch ansehen.

Beispiel und Übung

Beispiel:

Das Programm erzeugt eine definierte Anzahl von 'Zufallszahlen' und zählt dabei, wie viele dieser erzeugten Zahlen gerade und ungerade sind.

Für die Erzeugung der Zufallszahl werden 3 neue Funktionen eingesetzt. Die erste Funktion

int rand();

liefert eine 'Zufallszahl' zwischen 0 und RAND_MAX. RAND_MAX ist eine compilerabhängige Konstante, deren Wert z.B. beim VC++ 0x7FFF und beim MinGW-Compiler 0x7FFFFFFF beträgt. Da rand() natürlich keine 'Zufallszahl' liefern kann, sondern nur nach einem bestimmten Algorithmus verteilte Zahlen, wird zuerst mittels

time_t time( time_t *timer );

die aktuelle Uhrzeit ausgelesen. time(...) liefert die seit dem 1.1.1970 00:00Uhr vergangene Anzahl von Sekunden zurück. Dieser Wert wird in einen unsigned int Wert umgewandelt. Anschließend wird die Funktion

void srand( unsigned int seed );

aufgerufen, die den Zufallszahlen-Algorithmus initialisiert. Wird srand(...) immer mit dem gleichen Wert aufgerufen, so werden auch immer die gleichen 'Zufallszahlenreihen' durch rand() generiert.

Wenn Sie die Funktionen rand() und srand(...) verwenden müssen Sie die Header-Datei cstdlib einbinden und für die Funktion time(...) die Header-Datei ctime. Alle Funktionen liegen ebenfalls im Namensraum std!

Der Rest des Programms ist relativ einfach. Bei der generierten Zufallszahl wird in einer if-Abfrage das Bit 0 ausmaskiert. Bei ungeraden Zahlen ist das Bit 0 immer 1 (1=00000001, 3=00000011, 5= 00000101, ...) und bei geraden Zahlen 0. Je nach Ergebnis der Abfrage wird dann ein entsprechender Zähler um eins erhöht. Anschließend wird der Zähler für die Anzahl der erzeugten Zufallszahlen erhöht. Wurde die festgelegte Anzahl von Zahlen noch nicht erzeugt, erfolgt ein Sprung nach vorne im Programm.

Anzahl der geraden Zahlen: 510
Anzahl der ungeraden Zahlen: 490


// Beispiel zur if Verzweigung
// HINWEIS: Das Beispiel verwendet eine goto-Anweisung
// da bis jetzt noch keine Schleifen eingeführt wurden.


// Zuerst Dateien einbinden
#include <iostream>
#include <cstdlib>
#include <ctime>

using std::cout;
using std::endl;

// main() Funktion
int main ()
{
   // Anzahl der erzeugten Zufallszahlen
   const int MAXCOUNTER = 1000;

   // aktuelle Uhrzeit auslesen
   unsigned int actTime = static_cast<unsigned int>(std::time(NULL));
   // Zufallszahlen initialisieren
   std::srand (actTime);
   // Anzahl der erzeugten Zufallszahlen
   int counter = 0;
   // Zähler für gerade und gerade Zahlen
   int even=0, odd=0;
   // Zufallszahl
   int number;

   // Schleife
OnceAgain:
   // Zufallszahl generieren
   number = std::rand();
   // Falls Bit 0 gesetzt ist Zahl ungerade
   if (number&0x01 != 0)
      odd++;
   // sonst ist Zahl gerade
   else
      even++;
   // Anzahl der erzeugten Zufallszahlen erhöhen
   counter++;
   // Wenn weniger als MAXCOUNTER Zahlen erzeugt,
   // dann weiter Zahl erzeugen

   if (counter < MAXCOUNTER)
      goto OnceAgain;

   // Ergebnis ausgeben
   cout << "Anzahl der geraden Zahlen: " << even << endl;
   cout << "Anzahl der ungeraden Zahlen: " << odd << endl;
}

Übung:

Es soll ein kleines Taschenrechner-Programm erstellt werden das zwei Zahlen (Operanden) und einen Operator nach folgender Syntax einliest:

Operand1 Operator Operand2

Als Operator sind nur +, -, * und / zulässig. Wird ein anderer Operator eingegeben, soll eine entsprechende Fehlermeldung ausgegeben werden. Die Operanden sind als short-Werte einzulesen. Ein Überprüfung, ob die Operanden als short-Ganzzahl eingegeben wurden, muss nicht implementiert werden (kann aber).

Bei korrekter Eingabe ist das Ergebnis der eingegebenen Formel als Ganzzahl zu berechnen und auszugeben.

Formel nach folgender Syntax eingeben:
Operand1 Operator Operand2
Operator kann sein: + - * /
Formel ? 22 / 4
Ergebnis: 5

Lösung ansehen!