C++ Teil 5 – Bedingte Anweisungen

C++ Teil 5 – Bedingte Anweisungen

Inhalt

Bedingte Anweisung
Vergleichsoperatoren
Logische Operatoren
if – Anweisung
if-else – Anweisung
if-else – Kurzform
Bedingungsoperator
switch – Anweisung
Typische Fehler
Übungsaufgaben

Bedingte Anweisung

Bis jetzt hatten alle Beispiele einen starren Ablauf, d.h. es gab keine Verzweigungen. Im Folgenden werden wir uns anschauen, wie man ein Programm „entscheiden“ lassen kann, ob der eine oder der andere Codeabschnitt ausgeführt werden soll. Der erste Schritt dazu ist das if-Konstrukt.

begingter satz

Bleibst die Bedingung nicht erfüllt (=false), so wird die Anweisung nicht ausgeführt. Man kann es sich durch folgende Abbildung verdeutlichen.
if schema
Diese, oft im Leben vorkommende bedingte Tätigkeiten lassen sich auch in C++ „simulieren“. Doch bevor wir uns anschauen wie das genau funktioniert, müssen wir verstehen wie eine Bedingung konstruiert wird.

Vergleichsoperatoren

Mit Vergleichsoperatoren können zwei Werte mit einander verglichen werden, wobei ein Wert eine Variable oder eine Konstante sein kann.

Vergleichsoperatoren
Operatorname Operator in C++ Beispiel (x = 4, y = 9) Ergebnis des Beispiels
gleich == x == 4
x == y
true
false
ungleich != x != y
x != 4
true
false
größer als > y > x
x > 4
true
false
größer gleich >= x >= 4
y >= 233
true
false
kleiner als << x < y
y < x
true
false
kleiner gleich <= 2 <= y
y <= x
true
false
Wenn Sie sich nicht merken können, welches Zeichen ‚größer‘ und welches ‚kleiner‘ bedeutet, dann hier ein Tipp: Das kleiner-Zeichen < kann man zu einen K(kleiner) erweitern.

Beachten Sie, dass die Operatoren ‚ungleich‘, ‚kleiner gleich‘ und ‚größer gleich‘ nur in der Form !=, <=, >= und nicht in als =!, =<, >= akzeptiert werden.

Das Ergebnis eines Vergleichs ist immer true oder false. Man kann es sich mit folgendem Beispiel verdeutlichen:

// Beispiel zu Verglechsoperatoren

// Variablen deklarieren und initialisieren
int geschwindigkeitslimit = 80;
int geschwindigkeit = 74;

// Man stellt eine Bedingung(These) auf, dass der
// Geschwindigkeitslimit überschritten wurde.
// Die These kann nur richtig(true) oder falsch(false) sein.
bool abbremsen = geschwindigkeit > geschwindigkeitslimit;
cout <<"abbremsen: "<< abbremsen <<endl;

Es wird nur dann abgebremst, wenn die Geschwindigkeit das Limit überschreitet.
Also nichts weltbewegendes. Schauen wir uns als Nächstes logische Operatoren an.

Logische Operatoren

Es gibt drei logische Operatoren: UND, ODER und NICHT. Mit Hilfe der logischen Operatoren kann man Vergleichsoperatoren mit einander kombinieren und so noch komplexere Bedingungen aufstellen.

Ein paar Beispiele für Bedingungen:

  1. Das Wetter ist schlecht UND ich bin müde
  2. Es war ein rotes ODER ein blaues Auto
  3. Es war samstags ODER sonntags UND es regnete NICHT

Bedeutung der Verknüpfungen:

  • UND: Das Ergebnis ist nur dann wahr, wenn alle Teile der Bedingung wahr sind
  • ODER: Das Ergebnis ist nur dann wahr, wenn mindestens ein Teil der Bedingung wahr ist
  • NICHT: Das (Teil)Ergebnis wird negiert, d.h. seine Aussage wird genau umgedreht. Aus wahr wird unwahr und aus unwahr wird wahr
Logische Operatoren
Operatorname Operator in C++ Arbeitsweise Beispiel (x = 4, y = 9) Ergebnis des Beispiels
UND && true && true -> true
false && true -> false
true && false -> false
false && false -> false
(x==2) && (y == 5)
(x==3) && (y == 5)
true
false
ODER || true || true -> true
false || true -> true
true || false -> true
false || false -> false
(x==3) || (y == 5)
(x==45) || (y == 15)
true
false
NICHT ! (Ausrufezeichen) !true -> false
!false -> true
!(x==1) && (y == 5)
!(x==4) && !(y == 9)
true
false
// Man läuft durch die Stadt.
// Man hat genau passend Geld,
// um sich was zu essen und zu trinken zu kaufen.
// Man hat Durst aber kein Hunger.
bool geld_dabei = true;
bool durst = true;
bool hunger = false;

// Zu trinken kaufen, wenn man Geld dabei hat und durstig ist.
// true && true => true
bool was_zu_trinen_kaufen = geld_dabei && durst;

// Zu essen kaufen, wenn man Geld dabei hat und hungrig ist.
// true && false => false
bool was_zu_essen_kaufen = geld_dabei && hunger;

// Man gibt nur dann geld aus, wenn man sich etwas zu essen oder
// zu trinken kaufen möchte.
// true || false => true
bool geld_ausgeben = was_zu_trinen_kaufen || was_zu_essen_kaufen;

// Es ist nur dann was vom geld übrig geblieben, wenn man
// nicht getrunken oder nicht gegessen hat.
// (true && !false) || (!true && false) => (true) || (false) => true
bool geld_uebrig = (was_zu_trinen_kaufen && !was_zu_essen_kaufen) || (!was_zu_trinen_kaufen && was_zu_essen_kaufen);

Ich hoffe, es ist einigermaßen klar geworden, wie man eine Bedingung definiert.

In C++ gibts noch Operatoren & und |, welche Bitoperationen durchführen. Man sollte sie nicht mit && und || vertauschen, denn sie haben total andere Funktion.

if – Anweisung

Eigentlich haben wir über if-Anweisung schon alles gehört. Was noch unerwähnt geblieben ist, ist die Syntax.

if( Bedingung )
{
     Anweisung(en);
}

Wenn die Bedingung wahr ist, dann werden die Anweisungen in den geschweiften Klammern ausgeführt. Wenn die Bedingung falsch ist, so wirt der Block einfach übersprungen. Nichts Neues oder?
Ein kleines Programm, welches verdeutlichen soll, wie if verwendet wird.

// if-Beispiel

#include <iostream>
using namespace std;

int main(void)
{
    // Variable für die Eingabe deklarieren
    int zahl_1, zahl_2;

    // Dem Benutzer "Hallo" sagen
    cout<<"Hallo! Geben Sie bitte die 1. Zahl ein." <<endl;

    // den Wert einlesen
    cin>>zahl_1;

    // Dem Benutzer "Hallo" sagen
    cout<<"Hallo! Geben Sie bitte die 2. Zahl ein." <<endl;

    // den Wert einlesen
    cin>>zahl_2;

    if(zahl_1 == zahl_2)
    {
        cout<< "1.Zahl und 2.Zahl haben den gleichen Wert!"<<endl;
    }

    // Warten auf die Enter-Taste
    cout<<"Programm-Ende"<<endl;
    cin.get();

    return 0;
}

Eine if-Anweisung kann mehrere Anweisungen beinhalten und es können mehrere if-Anweisungen in einander verschachteln werden.
Im letzten Beispiel wird in die if-Anweisung durch folgende ersetzt.

if-Beispiel. Verschachtelung.
if(zahl_1 > zahl_2)
{
    // 2 Anweisungen
    cout<< "1.Zahl ist groesser"<<endl;
    cout<< " als 2.Zahl!"<<endl;

    if(zahl_1 < 1000)
    {
        cout<< "1.Zahl kleiner als 1000"<<endl;
    }
}

if-else – Anweisung

Eine if-else – Anweisung ist eine Erweiterung der if-Anweisung. Dem „Wenn…dann“ Satz wird noch das „ansonsten“ angehängt.

wenn - dann satz

Wird die Bedingung nicht erfüllt, so wird eine alternative Anweisung ausgeführt. Eine Grafik soll das Ganze noch mal verdeutlichen.
if else schema

if( Bedingung )
{
    // Anweisung(en), wenn die Bedingung wahr ist
}
else
{
    // Anweisung(en), wenn die Bedingung falsch ist
}

Und gleich ein Beispiel, damit es sitzt.

// if-else-Beispiel


#include <iostream>
using namespace std;

int main(void)
{
    // Variable für die Eingabe deklarieren
    int zahl_1, zahl_2;

    // Dem Benutzer "Hallo" sagen
    cout<<"Hallo! Geben Sie bitte die 1. Zahl ein." <<endl;

    // den Wert einlesen
    cin>>zahl_1;

    // Dem Benutzer "Hallo" sagen
    cout<<"Hallo! Geben Sie bitte die 2. Zahl ein." <<endl;

    // den Wert einlesen
    cin>>zahl_2;

    if(zahl_1 > zahl_2)
    {
        cout<< "1.Zahl ist groesser als 2.Zahl!"<<endl;
    }
    else
    {
        cout<< "1.Zahl ist kleiner als 2.Zahl!"<<endl;
    }

    // Warten auf die Enter-Taste
    cout<<"Programm-Ende"<<endl;
    cin.get();

    return 0;
}

Die if-else-Anweisung lässt sich noch weiter erweitern. Dazu bekommt der else-Teil einen if-Teil drangehängt und sieht dann folgendermaßen aus.

if( Bedingung_1 )
{
    // Anweisung(en), wenn Bedingung_1 wahr ist
}
else if( Bedingung_2 )
{
    // Anweisung(en), wenn Bedingung_2 wahr ist
}
else if( Bedingung_3 )
{
    // Anweisung(en), wenn Bedingung_3 wahr ist
}
else
{
    // Anweisung(en), wenn alle Bedingungen falsch sind
}

Es können beliebig viele else-if Teile aufeinander kommen. Der else-Teil am Ende ist optional.

Die Funktion von if-else-if wird durch folgende Grafik verdeutlicht (ohne else-Teil am ende).
if else if

So, das waren erstmal die grundlegenden Informationen. Jetzt kommt der Zusatzstoff.

if-else – Kurzform

Wenn nach if nur eine Anweisung kommt, so können die geschweiften Klammern weggelassen werden.

if( Bedingung )
    Nur eine Anweisung

Bei folgendem Code wird nur die erste Anweisung ausgeführt, die zweite wird immer ausgeführt.

if( Bedingung )
    Anweisung_1;
    Anweisung_2;

Für einen Anfänger empfehle ich, die Klammern immer zu setzen. Erweitert man den Programmcode und schreibt eine weitere Anweisung zu if, vergisst aber die Klammern zu setzen, so hat man einen logischen Fehler, der nur schwer zu lokalisieren ist. Also, aufpassen!

Was mit if geht, geht auch mit if-else.

if( Bedingung )
    Nur eine Anweisung
else
    Nur eine Anweisung

Auch hier sollte man aufpassen und sich immer im Klaren sein, dass nur eine Anweisung nach else ausgeführt wird.

Je nach Bedarf können zwei weitere Varianten verwendet werden.

if( Bedingung )
{
    Anweisung(en)
}
else
    Nur eine Anweisung
if( Bedingung )
    Nur eine Anweisung
else
{
    Anweisung(en)
}

Analog können die Klammern auch bei der if-else-if Konstruktion weggelassen werden, wenn nur eine Anweisung ausgeführt werden soll.

Bedingungsoperator

Neben oben vorgestellten kurzer Schreibweise von if-else gibt es noch eine weitere, die als Bedingungsoperator oder bedingte Bewertung genannt wird.

Die Syntax von bedingter Bewertung.

( Bedingung ) ? Anweisung_1 : Anweisung_2;

Funktional unterscheidet sich der Bedingungsoperator in keiner Weise von einer if-else-Anweisung. Wenn die Bedingung wahr ist, so wird die Anweisung_1 ausgeführt, ansonsten Anweisung_2. Die Bedingung muss nicht zwangsweise mit runden Klammern umschlossen werden, doch sollte man sich das angewöhnen diese immer zu setzen, weil dadurch die Lesbarkeit des Codes erhöht wird (man sieht sofort, was die Bedingung ist).

Die bedingte Bewertung hat den Vorteil, dass man sich Tipparbeit spart und wie viel soll das nächste Beispiel zeigen. Alle drei Varianten der if-else-Anweisung machen das gleiche.

// Beispiel: Bedingungsoperator
// ist die zahl größer als 10, so wird der zahl eine 12 dazu addiert,
// ansonsten eine 13 abgezogen


int zahl = 0;
cout<< "Bitte Zahl eingeben!" <<endl;
cin >> zahl;


// Normale if-else Form
if(zahl > 10)
{
    zahl += 12;
}
else
{
    zahl -= 13;
}


// kurze if-else Form
if(zahl > 10)
    zahl += 12;
else
    zahl -= 13;


// bedingte Bewertung
zahl += (zahl > 10) ? 12 : -13;

Es können mehrere Bedingungsoperatoren in einander verschachtelt werden. Man sollte aber der Lesbarkeit zu gute nicht übertreiben: maximal eine Verschachtlung in einem Block.

// Beispiel: Bedingungsoperator - Verschachtelung
int zahl = 0;

cout<< "Bitte Zahl eingeben!" <<endl;
cin >> zahl;

// bedingte Bewertung
// zahl > 20 => zahl = zahl + 14
// 10 < zahl < 20 => zahl = zahl + 15
// zahl < 10 => zahl = zahl +(-13)
zahl += (zahl > 10) ? ((zahl > 20) ? 14 : 15) : -13;

// Normale if-else Form
if(zahl > 10)
{
    if(zahl > 20)
    {
        zahl += 14;
    }
    else
    {
        zahl += 15;
    }
}
else
{
    zahl -= 13;
}
birneAls Faustregel gilt: Die bedingte Bewertung soll eine Zeile nicht überschreiten und nicht zu viele Verschachtlungen aufweisen, damit sie immer schön lesbar bleibt.

Ich spreche aus Erfahrung, wenn ich sage, dass der Bedingungsoperator bei den Anfängern nicht besonders beliebt ist, doch hat man die Vorteile erstmal entdeckt, so wird er wo immer es nur geht eingesetzt.

switch – Anweisung

Bevor wir zur switch-Anweisung übergehen, möchte ich ein weiteres if-else-if Beispiel zeigen.

char buchstabe = 0;

cout<< "Bitte einen Buchstaben (A,E,M,Y) eingeben! " <<endl;
cin >> buchstabe;

// Normale if-else-if Form

if('A' == buchstabe)
{
    cout <<"'A' ist der erste Buchstabe im Alphabet." <<endl;
}
else if('E' == buchstabe)
{
    cout <<"Der Buchstabe 'E' wird am meisten verwendet." <<endl;
}
else if('M' == buchstabe)
{
    cout <<" 'M' ist ein schoener Buchstabe " <<endl;
}
else if('Y' == buchstabe)
{
    cout <<"'Y' ist ein seltener Buchstabe." <<endl;
}
else
{
    cout << "Sie haben nicht A,E,M oder Y eingegeben." <<endl;
}

Was sofort auffällt ist, dass das Ganze unübersichtlich und somit unleserlich ist. Zudem schreibt man vieles doppelt: else if(‚X‘ == buchstabe). An dieser Stelle kommt switch ins Spiel.

switch ist eine Anweisung, die nur dazu dient den Code übersichtlicher zu machen.

// Sytax


switch ( Ausdruck )
{
    case Konstante_1:
        Anweisung(en);
        break;

    case Konstante_2:
        Anweisung(en);
        break;

    case Konstante_3:
        Anweisung(en);
        break;

    [...]

    default:
        Anweisung(en);
}

Als Ausdruck wird eine Variable übergeben, mit der weitere Vergleiche durchgeführt werden sollen. Wenn der übergebene Wert mit einer der Konstante (von oben nach unten) übereinstimmt, so wird ab dem Punkt alle Anweisungen bis zum nächsten break ausgeführt. Durch break wird die switch-Anweisung verlassen. Steht am Ende eines case kein break so werden auch Anweisungen von weiteren Fällen ausgeführt (Aufpassen:häufiger Fehler!). default-Anweisungen werden nur, dann ausgeführt, wenn keiner der Fälle zutrifft oder beim letzten Fall die break-Anweisung vergessen wurde. Das default-Teil ist optional.
Eine Grafik soll verdeutlichen wie switch funktioniert.

switch schema

Das obere if-else Beispiel mit einer switch-Anweisung.

char buchstabe = 0;

cout<< "Bitte einen Buchstaben(A,E,M, Y) eingeben! " <<endl;
cin >> buchstabe;

switch ( buchstabe )
{
    case 'A':
        cout <<"'A' ist der erste Buchstabe im Alphabet." <<endl;
        break;

    case 'E':
        cout <<"Der Buchstabe 'E' wird am meisten verwendet." <<endl;
        break;

    case 'M':
        cout <<" 'M' ist ein schoener Buchstabe " <<endl;
        break;

    case 'Y':
        cout <<"'Y' ist ein seltener Buchstabe." <<endl;
        break;

    default:
        cout << "Sie haben nicht A,E,M oder Y eingegeben." <<endl;
}

Wie man sieht ist der Code etwas übersichtlicher geworden.

Als nächstes möchte ich Sie auf einige Fehlerquellen hinweisen.

Typische Fehler

A:
Man will eine Anweisung ausführen, wenn die Variable den Wert 5 oder 46 hat. Ohne zu überlegen schreibt man so was hin:

int zahl = 0;

cin >> zahl;

if( zahl == 5 || 46 )
{
    // Anweisung
}

Sieht zunächst logisch aus, ist aber total falsch, den die Anweisung wird immer ausgeführt. Durch den ODER-Operator wird die Bedingung (zahl == 5 || 46) in zwei Teilbedingungen zerlegt:
1. Wenn zahl==5
2. Wenn 46
Der erste Teil funktioniert richtig und der zweite ist immer wahr, weil alle Zahlen außer Null als true interpretiert werden. Und so steht da: (xxx || true) und das ist wie wir bereits kennen gleich true.

Das wäre richtig:

int zahl = 0;

cin >> zahl;

if( zahl == 5 || zahl == 46 )
{
    // Anweisung
}

B:
Wenn Sie kurze if(-else) Schreibweise verwenden, vergessen Sie nicht, dass nur die erste Anweisung bedingt ausgeführt wird.

C:
Ein oft aufzutretender Fehler ist das Vergessen von break bei der Verwendung einer switch-Anweisung.

D:
Nehmen wir an, Sie möchten eine Variable mit einer Konstante vergleichen, vertippen sich aber und aus == wird =.

int zahl = 0;

cin >> zahl;

if( zahl = 5 )
{
    // Anweisung
}

zahl = 5 ist kein Vergleich, sondern eine Zuweisung. Diese wird vom Compiler akzeptiert und ausgeführt. In if steht somit immer true, d.h. die bedingten Anweisungen werden immer ausgeführt. Dieser Fehler ist sehr schwer zu finden, da der Compiler keine Warnung oder Fehlermeldung ausgibt. Um solche Fehler zu vermeiden, sollte man bei einem Vergleich eine Konstante immer auf die linke Seite stellen. Wenn man sich jetzt vertippt, bekommt man eine Fehlermeldung, denn einer Konstante kann kein Wert zugewiesen werden.

int zahl = 0;

cin >> zahl;

if( 5 = zahl ) // Fehler
{
    // Anweisung
}

Übungsaufgaben

  1. Was ist eine bedingte Anweisung? Konstruieren Sie 3 Sätze mit einer Bedingung.
  2. !true && true = ??? !(false && true) || false = ??? (33 && true) || false || true = ???
  3. Was ist der Unterschied zwischen if und if-else?
  4. Was ist ein Bedingungsoperator? Syntax? Vorteile?
  5. Beschreiben Sie die Funktionsweise der switch-Anweisung. Syntax?
  6. Erweitern Sie das Programm aus der Aufgabe 10 aus 3.Teil so, dass nur positive Werte eingegeben werden können. Wird ein negativer Wert eingegeben, so wird eine Meldung „Negativer Wert! -> Programm-Ende mit Enter Taste“ ausgegeben und das Programm wird durch die Enter-Taste beendet. Als Anweisung zum verlassen des Programms verwenden Sie return 0;.

Schreibe einen Kommentar