Inhalt
Bedingte Anweisung
Vergleichsoperatoren
Logische Operatoren
if – Anweisung
if-else – Anweisung
if-else – Kurzform
Bedingungsoperator
switch – Anweisung
Typische Fehler
Übungsaufgaben
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.
Bleibst die Bedingung nicht erfüllt (=false), so wird die Anweisung nicht ausgeführt. Man kann es sich durch folgende Abbildung verdeutlichen.
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.
Mit Vergleichsoperatoren können zwei Werte mit einander verglichen werden, wobei ein Wert eine Variable oder eine Konstante sein kann.
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 |
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.
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:
- Das Wetter ist schlecht UND ich bin müde
- Es war ein rotes ODER ein blaues Auto
- 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
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.
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; } }
Eine if-else – Anweisung ist eine Erweiterung der if-Anweisung. Dem „Wenn…dann“ Satz wird noch das „ansonsten“ angehängt.
Wird die Bedingung nicht erfüllt, so wird eine alternative Anweisung ausgeführt. Eine Grafik soll das Ganze noch mal verdeutlichen.
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).
So, das waren erstmal die grundlegenden Informationen. Jetzt kommt der Zusatzstoff.
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.
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; }
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.
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.
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.
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 }
- Was ist eine bedingte Anweisung? Konstruieren Sie 3 Sätze mit einer Bedingung.
- !true && true = ??? !(false && true) || false = ??? (33 && true) || false || true = ???
- Was ist der Unterschied zwischen if und if-else?
- Was ist ein Bedingungsoperator? Syntax? Vorteile?
- Beschreiben Sie die Funktionsweise der switch-Anweisung. Syntax?
- 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;.