Kontroll- anweisungen: Teil 2
Transcription
Kontroll- anweisungen: Teil 2
1 4 Kontrollanweisungen: Teil 2 2006 Pearson Education, Inc. All rights reserved. 2 4.1 Einführung 4.2 Grundlagen der zählerkontrollierten Wiederholung 4.3 for Wiederholungsanweisung 4.4 Beispiele für die Nutzung der for Anweisung 4.5 do…while Wiederholungsanweisung 4.6 switch Anweisung zur Mehrfachauswahl 4.7 break und continue Anweisung 4.8 Logische Operatoren 4.9 Verwechseln von Gleichheits- (==) und Zuweisungsoperator (=) 2006 Pearson Education, Inc. All rights reserved. 3 4.1 Einführung • Fortsetzung der Diskussion der strukturierten Programmierung – Einführung der übrigen Kontrollstrukturen von C • for • do…while • switch 2006 Pearson Education, Inc. All rights reserved. 4.2 Grundlagen der zählerkontrollierten Wiederholung 4 • Zählerkontrollierte Wiederholung erfordert: – Den Namen einer Kontrollvariablen (Schleifenzähler) – Den Anfangswert der Kontrollvariablen – Eine Schleifenbedingung, die den Endwert der Kontrollvariablen testet – Inkrementierung/Dekrementierung der Kontrollvariablen in jedem Schleifendurchlauf (Iteration) 2006 Pearson Education, Inc. All rights reserved. 1 // Fig. 4.1: fig04_01.c 2 // Counter-controlled repetition. 3 #include <stdio.h> Outline 5 4 5 int main( void ) 6 { 7 fig04_01.c unsigned int counter = 1; // declare and initialize control variable 8 9 while( counter <= 10 ) { // loop-continuation condition 10 printf( "%u ", counter ); 11 ++counter; // increment control variable by 1 12 (1 von 1) } // end while 13 14 puts( "" ); // output a newline 15 } // end main 1 2 3 4 5 6 7 8 9 10 2006 Pearson Education, Inc. All rights reserved. 6 4.3 for Wiederholungsanweisung •for Wiederholungsanweisung – Legt die Details der zählerkontrollierten Wiederholung in einer einzigen Codezeile fest 2006 Pearson Education, Inc. All rights reserved. 1 // Fig. 4.2: fig04_02.c 2 // Counter-controlled repetition with the for statement. 3 #include <stdio.h> Outline 7 4 5 int main( void ) 6 { 7 fig04_02.c unsigned int counter; (1 von 1) 8 9 // for statement header includes initialization, 10 // loop-continuation condition and increment. 11 for( counter = 1; counter <= 10; ++counter ) 12 printf( "%u ", counter ); 13 14 puts( "" ); // output a newline Inkrement für counter 15 } // end main 1 2 3 4 5 6 7 8 9 10 Schleifentest auf counters Endwert Die Kontrollvariable ist counter mit dem Anfangswert 1 2006 Pearson Education, Inc. All rights reserved. 8 Häufiger Programmierfehler Verwendung eines falschen Vergleichsoperators oder eines nicht korrekten Endwertes für den Schleifenzähler in der Bedingung einer while oder for Anweisung führt oft dazu, dass die Schleife einmal mehr oder weniger als beabsichtigt durchlaufen wird (‘ off-by-one error’). 2006 Pearson Education, Inc. All rights reserved. 9 Praxis-Tipp Um ‘off-by-one errors’ zu vermeiden, kann man beginnend mit Eins zählen und den Endwert der Schleifenvariablen mit dem <= Vergleichsoperator in der Bedingung einer while oder for Anweisung verwenden. Üblich ist auch das sogenannte Null-basierte Zählen, bei dem, um eine Schleife zehnmal zu durchlaufen, counter mit Null initialisiert wird und die Schleifenbedingung dann die Form counter < 10 hat. 2006 Pearson Education, Inc. All rights reserved. 10 4.3 for Wiederholungsanweisung • Allgemeine Form der for Anweisung – for( Initialisierung; Schleifenbedingung; Inkrementierung ) Anweisung; • Kann auch realisiert werden durch: – Initialisierung; while( Schleifenbedingung ) { Anweisung; Inkrementierung; } 2006 Pearson Education, Inc. All rights reserved. 11 Häufiger Programmierfehler Wird die Kontrollvariable einer for Anweisung im Initialisierungsabschnitt des Schleifenkopfs deklariert (das ist beim sog. ANSI-C (C90) - und bei Visual C++ bis zur Version 2012 - nicht erlaubt), verursacht eine Nutzung dieser Kontrollvariablen nach dem Schleifenkörper eine Fehlermeldung des Compilers. 2006 Pearson Education, Inc. All rights reserved. 12 Häufiger Programmierfehler Werden Kommas statt der geforderten Semikolons in einem for Kopf verwendet, ist dies ein Syntaxfehler. 2006 Pearson Education, Inc. All rights reserved. 13 Häufiger Programmierfehler Wird direkt neben der schließenden Klammer des for Kopfes ein Semikolon gesetzt, erzeugt dies eine for Anweisung, deren Körper nur aus einer leeren Anweisung besteht. Dies ist normalerweise ein logischer Fehler. 2006 Pearson Education, Inc. All rights reserved. 14 Betrachtung zum Software Engineering Ein Semikolon direkt hinter einem for Kopf wird manchmal benutzt, um eine sogenannte Verzögerungsschleife zu erzeugen. Eine solche for Schleife mit leerem Körper führt die angegebene Anzahl von Iterationen durch, indem sie einfach nur zählt. Diese Schleife kann z.B. Ausgaben auf eine gewünschte Weise verzögern. In dieser einfachen Form ist eine solche Verzögerungszeit jedoch nicht portabel, weil abhängig vom verwendeten Prozessor. 2006 Pearson Education, Inc. All rights reserved. 15 Tipp zur Fehlervermeidung Es ist zwar möglich, den Wert der Kontrollvariablen im Körper einer for Anweisung zu ändern, dies sollte jedoch unbedingt vermieden werden, weil es zu subtilen logischen Fehlern führen kann. 2006 Pearson Education, Inc. All rights reserved. 4.4 Beispiele für die Nutzung der for Anweisung 16 • for Anweisungen – Änderung der Kontrollvariablen von 1 bis 100 in Schritten von 1 • for( i = 1; i <= 100; ++i ) – Änderung der Kontrollvariablen von 100 bis 1 in Schritten von -1 • for( i = 100; i >= 1; --i ) – Änderung der Kontrollvariablen von 7 bis 77 in Schritten von 7 • for( i = 7; i <= 77; i += 7 ) – Änderung der Kontrollvariablen von 20 bis 2 in Schritten von -2 • for( i = 20; i >= 2; i -= 2 ) – Änderung der Kontrollvariablen über: 2, 5, 8, 11, 14, 17, 20 • for( i = 2; i <= 20; i += 3 ) – Änderung der Kontrollvariablen über : 99, 88, 77, …, 22, 11, 0 • for( i = 99; i >= 0; i -= 11 ) 2006 Pearson Education, Inc. All rights reserved. 4.4 Beispiele für die Nutzung der for Anweisung 17 • Wird in einer Schleife, die rückwärts zählt, ein Datentyp für die Kontrollvariable verwendet, der keine negativen Werte annehmen kann, darf die Schleifenbedingung auch nicht versuchen, mit negativen Werten zu arbeiten: unsigned int i; for( i = 100; i >= 0; --i ) { ... } -> Endlosschleife! (Da i als unsigned int bei einer Dekrementierung von 0 den größten darstellbaren positiven Wert annimmt.) 2006 Pearson Education, Inc. All rights reserved. 18 Häufiger Programmierfehler Wenn in einer Schleife, die rückwärts zählt, in der Schleifenbedingung der falsche Vergleichsoperator verwendet wird (wie z.B. i <= 1 statt i >= 1 in einer Schleife, die auf 1 herunterzählt) oder Schleifenbedingung und Typ der Kontrollvariablen nicht zusammenpassen, entsteht ein logischer Fehler bei der Ausführung des Programms. 2006 Pearson Education, Inc. All rights reserved. 4.4 Beispiele für die Nutzung der for Anweisung 19 • Anwendung: Aufsummieren der geraden Zahlen von 2 bis 100 • Fig. 4.5 nutzt eine for Anweisung, um die Summe aller geraden Zahlen von 2 bis 100 zu bilden und auszugeben. 2006 Pearson Education, Inc. All rights reserved. 1 // Fig. 4.5: fig04_05.c 2 // Summing integers with the for statement. 3 #include <stdio.h> Outline 20 4 5 int main( void ) 6 { fig04_05.c 7 unsigned int total = 0; // initialize total 8 unsigned int number; // number to be added 9 10 // total even integers from 2 through 100 11 for( number = 2; number <= 100; number += 2 ) 12 total += number; 13 14 number läuft von 2 bis (1 von 1) 100 in 2er-Schritten Aktueller Wert von number wird zu total addiert printf( "Sum is %u\n", total ); // display sum 15 } // end main Sum is 2550 2006 Pearson Education, Inc. All rights reserved. 21 Praxis-Tipp Im Initialisierungs- und Inkrementierungsabschnitt einer for Anweisung sollten nur Ausdrücke, die die Kontrollvariable betreffen, stehen. Manipulationen von anderen Variablen sollten entweder vor der Schleife stattfinden (falls sie nur einmal ausgeführt werden sollen, wie Initialierungsanweisungen) oder im Schleifenkörper (falls sie einmal pro Schleifenduchlauf ausgeführt werden sollen, wie Inkrementierungsanweisungen). 2006 Pearson Education, Inc. All rights reserved. 4.4 Beispiele für die Nutzung der for Anweisung 22 • Beispiel: Zinseszins-Berechnung – 1000 Euro (vorhanden im Jahr 2010) sollen mit 2% verzinst werden. – Das jeweils vorhandene Kapital am Ende der Jahre 2010 bis 2020 soll in Form einer Tabelle ausgegeben werden. 2006 Pearson Education, Inc. All rights reserved. 4.4 Beispiele für die Nutzung der for Anweisung 23 1 Initialisiere das Kapital auf 1000 Euro 2 Initialisiere den Zinssatz auf 2 Prozent 3 Initialisiere Startjahr auf 2010 und Endjahr auf 2020 4 5 Für jedes Jahr von Startjahr bis Endjahr 6 Gib Jahr und Kapital aus 7 Addiere Kapital * Zinssatz zum vorhandenen Kapital Fig. 4.5 | Pseudocode für die Zinseszins-Berechnung 2006 Pearson Education, Inc. All rights reserved. 1 // Fig. 4.6: fig04_06.c 2 // Compound interest calculations with for. 3 #include <stdio.h> 4 5 6 int main( void ) { Outline 24 Gleitpunkt-Konstanten haben standardmäßig den Typ double fig04_06.c 7 double amount = 1000.0; // initial amount before interest 8 double rate = .02; // interest rate 9 unsigned int year, startYear = 2010, endYear = 2020; // range of years (1 von 1) 10 11 // display table column header 12 printf( "%4s%21s\n", "Year", "Amount on deposit" ); 13 // calculate amount on deposit for each of the years 14 for( year = startYear; year <= endYear; ++year ) { 15 // output one table row 16 printf( "%4u%21.2f\n", year , amount ); 17 // calculate new amount for specified year 18 amount += amount * rate; 19 Legt fest, dass die ausgegebenen Strings bzw. Zahlen in Feldern der Breite 4 und 21 erscheinen } // end for 20 } // end main Year 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 Amount on deposit 1000.00 1020.00 1040.40 1061.21 1082.43 1104.08 1126.16 1148.69 1171.66 1195.09 1218.99 2006 Pearson Education, Inc. All rights reserved. 4.4 Beispiele für die Nutzung der for Anweisung 25 • Formatierung von numerischen Ausgaben – Um die Variable amount auszugeben, wird der Umwandlungsspezifizierer %21.2f benutzt. – Die 21 gibt hierbei die Feldbreite des Feldes an, in das der Wert ausgegeben wird. – Eine Feldbreite von 21 besagt, dass der ausgegebene Wert in 21 Druckspalten erscheint und dabei standardmäßig rechtsbündig dargestellt wird. – Um einen Wert linksbündig darzustellen, muss ein - (Minuszeichen) zwischen % und der Feldbreite stehen. – Die 2 nach dem Dezimalpunkt gibt die Genauigkeit an (d.h. die Anzahl der Dezimalstellen). 2006 Pearson Education, Inc. All rights reserved. 26 Praxis-Tipp Für monetäre Berechnungen sollten keine Variablen vom Typ float oder double verwendet werden. Die Ungenauigkeit von Gleitpunktzahlen kann zu falschen Werten bei solchen Rechnungen führen. Monetäre Berechnungen sollten auf der Rechnung mit ganzen Zahlen basieren. 2006 Pearson Education, Inc. All rights reserved. 27 4.5 do…while Wiederholungsanweisung •do…while Anweisung – Funktioniert wie die while Anweisung – Testet jedoch die Schleifenbedingung, nachdem der Schleifenkörper ausgeführt wurde • Der Schleifenkörper wird immer mindestens einmal ausgeführt. 2006 Pearson Education, Inc. All rights reserved. 28 Praxis-Tipp Bei der do...while Anweisung sollten immer geschweifte Klammern stehen. Auf diese Weise werden while Anweisung und do...while Anweisung weniger leicht verwechselt. 2006 Pearson Education, Inc. All rights reserved. 1 // Fig. 4.7: fig04_07.c 2 // do...while repetition statement. 3 #include <stdio.h> Outline 29 4 5 int main( void ) 6 { 7 fig04_07.c unsigned int counter = 1; // initialize counter (1 von 1) 8 9 do 10 { 11 printf( "%u ", counter ); // display counter 12 ++counter; // increment counter 13 } while( counter <= 10 ); // end do...while 14 15 puts( "" ); // output a newline 16 } // end main 1 2 3 4 5 6 7 8 9 10 2006 Pearson Education, Inc. All rights reserved. 30 Fig. 4.8 | UML Aktivitätsdiagramm für die do...while Anweisung aus Fig. 4.7. 2006 Pearson Education, Inc. All rights reserved. 4.6 switch Anweisung zur Mehrfachauswahl 31 • Einlesen von einzelnen Zeichen – getchar() • Liest ein beliebiges Zeichen von der Tastatur (einschließlich Leerraumzeichen) – EOF • Konstante, die in <stdio.h> definiert ist • Wird am Ende eines Eingabestroms automatisch erzeugt • Kann mit der Tastatur erzeugt werden durch • <Strg> z bei Windows • <Strg> d bei UNIX/Linux 2006 Pearson Education, Inc. All rights reserved. 32 Portabilitäts-Tipp Die Tatsache, dass man auf die symbolische Konstante EOF statt auf –1 testet, macht Programme portabler. Der C Standard legt fest, dass EOF ein negativer ganzzahliger Wert ist (aber nicht unbedingt –1), so dass EOF verschiedene Werte auf unterschiedlichen Systemen haben kann. 2006 Pearson Education, Inc. All rights reserved. 4.6 switch Anweisung zur Mehrfachauswahl 33 •switch Anweisung – Wird für Mehrfachauswahl genutzt – Testet eine Variable oder einen Ausdruck • Diese werden mit einem konstanten ganzzahligen Ausdruck verglichen, um zwischen verschiedenen möglichen Aktionen zu unterscheiden. 2006 Pearson Education, Inc. All rights reserved. 34 Fig. 4.9 | UML Aktivitätsdiagramm einer switch Anweisung mit break Anweisungen. 2006 Pearson Education, Inc. All rights reserved. 4.6 switch Anweisung zur Mehrfachauswahl 35 •switch Anweisung – Kontrollausdruck • Ausdruck in Klammern nach dem Schlüsselwort switch – case Label • Werden mit dem Kontrollausdruck verglichen • Anweisungen, die hinter dem passenden case Label stehen, werden ausgeführt. – Geschweifte Klammern um mehrere Anweisungen hinter einem case Label sind nicht nötig. – Eine break Anweisung bewirkt, dass die Programmausführung mit der ersten Anweisung nach dem switch fortgesetzt wird. • Ohne eine break Anweisung läuft die Programmausführung in das nächste case Label. 2006 Pearson Education, Inc. All rights reserved. 4.6 switch Anweisung zur Mehrfachauswahl 36 •switch Anweisung – default Case • Wird ausgeführt, wenn kein passendes case Label gefunden wird • Ist optional – Falls kein passendes case Label gefunden wird und kein default Case existiert wird die Programmausführung einfach hinter dem switch fortgesetzt. 2006 Pearson Education, Inc. All rights reserved. 37 Häufiger Programmierfehler Vergisst man eine break Anweisung, obwohl sie nötig wäre, führt dies zu einem logischen Fehler in der switch Anweisung. 2006 Pearson Education, Inc. All rights reserved. 4.6 switch Anweisung zur Mehrfachauswahl 38 • Beispiel: Häufigkeit von Notenwerten – Eine Liste von Notenwerten, die in Form der Buchstaben A, B, C, D und F vorliegt, soll vom Nutzer eingegeben werden. – Das Programm soll die Häufigkeit der einzelnen Notenwerte bestimmen und in Form einer Tabelle ausgeben. 2006 Pearson Education, Inc. All rights reserved. 1 // Fig. 4.10: fig04_10.c 2 // Counting A, B, C, D and F grades. 3 #include <stdio.h> Outline 39 4 5 int main( void ) 6 { 7 fig04_10.c int grade; // one grade (or possibly EOF) 8 unsigned int aCount = 0; // count of A grades 9 unsigned int bCount = 0; // count of B grades 10 unsigned int cCount = 0; // count of C grades 11 unsigned int dCount = 0; // count of D grades 12 unsigned int fCount = 0; // count of F grades (1 von 3) Zählervariablen für jede Notenkategorie 13 14 puts( "Enter the letter grades." ); 15 puts( "Enter the EOF character to end input." ); 16 grade ist der Kontrollausdruck 17 // loop until user types end-of-file key sequence 18 while( ( grade = getchar() ) != EOF ) { 19 // determine which grade was entered 20 switch( grade ) { // switch statement nested in while 21 case 'A': // grade was uppercase A 22 case 'a': // or lowercase a 23 ++aCount; // increment aCount 24 break; // necessary to exit switch break Anweisung überträgt die Kontrolle hinter das Ende der switch Anweisung 25 26 case 'B': // grade was uppercase B 27 case 'b': // or lowercase b 28 ++bCount; // increment bCount 29 break; // exit switch 2006 Pearson Education, Inc. All rights reserved. 30 31 case 'C': // grade was uppercase C 32 case 'c': // or lowercase c 33 ++cCount; // increment cCount 34 break; // exit switch Outline 40 fig04_10.c 35 36 case 'D': // grade was uppercase D 37 case 'd': // or lowercase d 38 ++dCount; // increment dCount 39 break; // exit switch (2 von 3) 40 41 case 'F': // grade was uppercase F 42 case 'f': // or lowercase f 43 ++fCount; // increment fCount 44 break; // exit switch 45 46 case '\n': // ignore newlines, 47 case '\t': // tabs, 48 case ' ': 49 // and spaces in input break; // exit switch 50 51 default weist den Nutzer auf ungültige eingegebene Zeichen hin default: // catch all other characters 52 printf( "Incorrect letter grade entered." ); 53 puts( " Enter a new grade." ); 54 break; // optional; will exit switch anyway 55 56 } // end switch } // end while 2006 Pearson Education, Inc. All rights reserved. 57 58 // output summary of results 59 puts( "\nNumber of students who received each letter grade:" ); 60 printf( "A: %u\n", aCount ); // display number of A grades 61 printf( "B: %u\n", bCount ); // display number of B grades 62 printf( "C: %u\n", cCount ); // display number of C grades 63 printf( "D: %u\n", dCount ); // display number of D grades 64 printf( "F: %u\n", fCount ); // display number of F grades Outline 41 fig04_10.c (3 von 3) 65 } // end function main Enter the letter grades. Enter the EOF character to end input. aaabbbcccdddfffFFFAAAeee a a a Incorrect letter grade entered. Enter a new grade. Incorrect letter grade entered. Enter a new grade. Incorrect letter grade entered. Enter a new grade. ^Z Number of students who received each letter grade: A: 9 B: 3 C: 3 D: 3 F: 6 2006 Pearson Education, Inc. All rights reserved. 42 Häufiger Programmierfehler Lässt man das Leerzeichen zwischen dem Wort case und dem ganzzahligen Testwert in einer switch Anweisung weg, kann ein logischer Fehler entstehen. Schreibt man etwa case3: statt case 3: so erzeugt man einfach ein nicht benutztes Label. Die vorgesehene Aktion, die zum Wert 3 des Kontrollausdrucks gehört, wird nicht ausgeführt. 2006 Pearson Education, Inc. All rights reserved. 43 Häufiger Programmierfehler Ein Ausdruck, der Variablen enthält (z.B. a + b), im case Label einer switch Anweisung ist ein Syntaxfehler. 2006 Pearson Education, Inc. All rights reserved. 44 Praxis-Tipp Ein default Case in switch Anweisungen sollte immer vorgesehen werden. Cases in einer switch Anweisung ohne einen default Case, die nicht explizit getestet werden, werden sonst einfach ignoriert – was leicht übersehen werden kann. Obwohl die einzelnen case Pfade und der default Case Pfad in beliebiger Reihenfolge geschrieben werden können, schreibt man den default Pfad normalerweise als Letzten. 2006 Pearson Education, Inc. All rights reserved. 45 Praxis-Tipp In einer switch Anweisung, wo der default Pfad als Letzter steht, benötigt dieser keine break Anweisung. Oft wird dieses break aus Symmetriegründen aber trotzdem geschrieben. 2006 Pearson Education, Inc. All rights reserved. 46 Häufiger Programmierfehler Beim Einlesen von Zeichen sollte man darauf achten, dass auch Zeilenwechsel und andere Leerraumzeichen geeignet verarbeitet werden. Sonst können logische Fehler entstehen. 2006 Pearson Education, Inc. All rights reserved. 4.6 switch Anweisung zur Mehrfachauswahl 47 • Ganzzahlige Datentypen – short • Abkürzung für short int • Mindestbereich ist - 32 768 bis + 32 767 – long • Abkürzung für long int • Mindestbereich ist - 2 147 483 648 bis + 2 147 483 647 – long long • Abkürzung für long long int • Mindestbereich ist (- 263 + 1) bis (+ 263 - 1) – int • Äquivalent zu short oder long auf den meisten Systemen – char • Kann auch zur Darstellung kleiner ganzer Zahlen verwendet werden (- 128 bis + 127 ) 2006 Pearson Education, Inc. All rights reserved. 48 Portabilitäts-Tipp Da ints auf unterschiedlichen Systemen verschieden groß sein können, sollte long oder long long verwendet werden, wenn erwartet wird, dass ganze Zahlen außerhalb des Bereichs von – 32 768 bis +32 767 verarbeitet werden und wenn das Programm auf unterschiedlichen Systemen laufen soll. 2006 Pearson Education, Inc. All rights reserved. 49 Tipp zur Performanz Wenn Speicherplatz knapp ist, kann es günstiger sein, die kleineren ganzzahligen Datentypen zu benutzen. Die Nutzung von kleineren ganzzahligen Datentypen kann ein Programm langsamer machen, da die entsprechenden Maschinenbefehle eventuell nicht so effizient sind wie für Integer, deren Größe der Wortbreite des Rechners entsprechen (z.B. 32 Bit auf einer 32-Bit Maschine). 2006 Pearson Education, Inc. All rights reserved. 50 4.7 break und continue Anweisung • break / continue Anweisungen – Ändern den Kontrollfluss • break Anweisung – Bewirkt den sofortigen Ausstieg aus einer Kontrollstruktur – Wird in while, for, do…while oder switch Anweisungen benutzt • continue Anweisung – Überspringt die restlichen Anweisungen in einem Schleifenkörper • Fortsetzung mit Inkrementierung in for Schleifen • Fortsetzung mit Schleifentest in while / do…while Schleifen – Danach wird die nächste Iteration ausgeführt. – Wird in while, for oder do…while Anweisungen benutzt 2006 Pearson Education, Inc. All rights reserved. 1 // Fig. 4.13: fig04_13.c 2 // break statement exiting a for statement. 3 #include <stdio.h> Outline 51 4 5 int main( void ) 6 { 7 10 Iterationen unsigned int count; // control variable 8 9 10 11 for( count = 1; count <= 10; ++count ) { // loop 10 times if( count == 5 ) break; // break loop only if count is 5 12 13 14 fig04_13.c (1 von 1) Ausstieg aus for, wenn count gleich 5 ist printf( "%u ", count ); // display value of count } // end for 15 16 printf( "\nBroke out of loop at count == %u\n", count ); 17 } // end main 1 2 3 4 Broke out of loop at count == 5 2006 Pearson Education, Inc. All rights reserved. 1 // Fig. 4.14: fig04_14.c 2 // continue statement exiting a for statement. 3 #include <stdio.h> Outline 52 4 5 int main( void ) 6 { 7 fig04_14.c unsigned int count; // control variable 10 Iterationen 8 9 10 11 for( count = 1; count <= 10; ++count ) { // loop 10 times if( count == 5 ) continue; // skip remaining code in loop body 12 13 14 (1 von 1) printf( "%u ", count ); // display value of count Überspringen von Zeile 13 und weiter mit Zeile 9, wenn count gleich 5 ist } // end for 15 16 puts( "\nUsed continue to skip printing the value 5" ); 17 } // end main 1 2 3 4 6 7 8 9 10 Used continue to skip printing the value 5 2006 Pearson Education, Inc. All rights reserved. 53 Praxis-Tipp Es gibt Programmierer, die der Auffassung sind, dass break und continue dem Prinzip der strukturierten Programmierung widersprechen. Da die gleichen Effekte, die break und continue haben, auch mit strukturierten Programmiertechniken erzielt werden können, kann man auf diese Anweisungen verzichten. Die meisten Programmierer halten den Einsatz von break und continue jedoch für akzeptabel. 2006 Pearson Education, Inc. All rights reserved. 54 Tipp zur Performanz Sinnvoll eingesetzte break und continue Anweisungen sind in der Regel performanter als die entsprechenden strukturierten Programmiertechniken. 2006 Pearson Education, Inc. All rights reserved. 55 4.8 Logische Operatoren • Logische Operatoren – Erlauben die Realisierung von komplexen Bedingungen • Durch Kombination von mehreren einfachen Bedingungen • Logische Operatoren in C – – – && (logisches UND) || (logisches ODER) ! (logisches NICHT) 2006 Pearson Education, Inc. All rights reserved. 56 Ausdruck1 Ausdruck2 Ausdruck 1 && Ausdruck 2 0 0 1 1 0 1 0 1 0 0 0 1 Ausdruck1 Ausdruck2 Ausdruck1 || Ausdruck2 0 0 1 1 0 1 0 1 0 1 1 1 Fig. 4.15 | Wahrheitstabelle für && (logisches UND) und für || (logisches ODER). 2006 Pearson Education, Inc. All rights reserved. 57 Häufiger Programmierfehler Obwohl 3 < x < 7 als mathematische Bedingung korrekt ist, kann es so nicht in C geschrieben werden. Die Realisierung dieser Bedingung in C lautet ( 3 < x ) && ( x < 7 ). 2006 Pearson Education, Inc. All rights reserved. 58 4.8 Logische Operatoren • ‘Kurzschluss’-Auswertung von komplexen Bedingungen – Teile eines Ausdrucks, der && oder || Operatoren enthält, werden nur solange ausgewertet, bis klar ist, dass der gesamte Ausdruck 0 oder 1 ist. – Beispiel ( 3 < x ) && ( x < 7 ) – Stoppt sofort, falls x kleiner oder gleich 3 ist. • Da dann die linke Seite 0 ist, muss der ganze Ausdruck 0 sein. 2006 Pearson Education, Inc. All rights reserved. 59 Tipp zur Performanz In Ausdrücken, die den && Operator nutzen, und für die die einzelnen Bedingungen unabhängig voneinander sind, sollte die Bedingung, die am wahrscheinlichsten 0 ist, am weitesten links stehen. In Ausdrücken mit dem || Operator sollte die Bedingung, die am wahrscheinlichsten 1 ist, am weitesten links stehen. Dieser Gebrauch der ‘Kurzschluss’-Auswertung kann die Ausführungs-zeit eines Programms reduzieren. 2006 Pearson Education, Inc. All rights reserved. 60 4.8 Logische Operatoren • Der logische Negations (!) Operator – Unärer Operator – Gibt 1 zurück, wenn sein Operand 0 ist und umgekehrt – Beispiel if( !( grade == sentinelValue ) ) printf( "The next grade is %d\n", grade ); ist äquivalent mit: if( grade != sentinelValue ) printf( "The next grade is %d\n", grade ); 2006 Pearson Education, Inc. All rights reserved. 1 // Fig. 4.18: fig04_18.c 2 3 // Logical operators (ANSI C Version). #include <stdio.h> Outline 61 4 5 int main( void ) 6 { 7 // create truth table for && (logical AND) operator 8 puts( "Logical AND (&&)" ); 9 printf( "0 && 0: %d\n", 0 && 0 ); 10 printf( "0 && 1: %d\n", 0 && 1 ); 11 printf( "1 && 0: %d\n", 1 && 0 ); 12 printf( "1 && 1: %d\n", 1 && 1 ); fig04_18.c Ausgabe der Wahrheitstabelle für logisches UND (1 von 2) 13 14 15 // create truth table for || (logical OR) operator puts( "\nLogical OR (||)" ); 16 printf( "0 || 0: %d\n", 0 || 0 ); 17 printf( "0 || 1: %d\n", 0 || 1 ); 18 printf( "1 || 0: %d\n", 1 || 0 ); 19 printf( "1 || 1: %d\n", 1 || 1 ); Ausgabe der Wahrheitstabelle für logisches ODER 20 21 // create truth table for ! (logical negation) operator 22 puts( "\nLogical NOT (!)" ); 23 printf( "! 0: %d\n", ! 0 ); 24 printf( "! 1: %d\n", ! 1 ); Ausgabe der Wahrheitstabelle für logisches NICHT 25 } // end main 2006 Pearson Education, Inc. All rights reserved. Logical 0 && 0: 0 && 1: 1 && 0: 1 && 1: AND (&&) 0 0 0 1 Outline Logical 0 || 0: 0 || 1: 1 || 0: 1 || 1: OR (||) 0 1 1 1 fig04_18.c 62 (2 von 2) Logical NOT (!) ! 0: 1 ! 1: 0 2006 Pearson Education, Inc. All rights reserved. 63 Operatoren Assoziativiät Typ () links nach rechts Klammern ++ -- static_cast< type >() links nach rechts unär (Postfix) ++ -- + rechts nach links unär (Präfix) * + / - % << >> < <= == != - ! links nach rechts multiplikativ links nach rechts additiv links nach rechts Ausgabe / Eingabe > links nach rechts relational >= links nach rechts Gleichheit && links nach rechts logisches UND || links nach rechts logisches ODER ?: rechts nach links konditional = , += -= *= /= %= rechts nach links Zuweisung links nach rechts Komma Fig. 4.19 | Operator-Vorrang und Assoziativität. 2006 Pearson Education, Inc. All rights reserved. 4.9 Verwechseln von Gleichheits- (==) und Zuweisungsoperator (=) 64 • Versehentliches Vertauschen der Operatoren == (Gleichheit) und = (Zuweisung) – Häufiger Fehler • Zuweisungsanweisungen geben einen Wert zurück (den zugewiesenen Wert). • Ausdrücke, die einen Wert haben, können als Entscheidungsgrundlage dienen. – Null entspricht ‘falsch’, Ungleich Null entspricht ‘wahr’ – Führt üblicherweise nicht zu Syntaxfehlern • Einige Compiler geben eine Warnung aus, wenn = in einem Kontext benutzt wird, wo normalerweise == erwartet wird. 2006 Pearson Education, Inc. All rights reserved. 4.9 Verwechseln von Gleichheits- (==) und Zuweisungsoperator (=) 65 • Beispiel if( payCode == 4 ) printf( "You get a bonus!\n" ); – Falls paycode den Wert 4 hat, gibt es eine Prämie. • Falls == mit = vertauscht wird: if( payCode = 4 ) printf( "You get a bonus!\n" ); – paycode wird auf 4 gesetzt (egal, welchen Wert es vorher hatte). – Die Bedingung ist ‘wahr’ (da 4 ungleich Null ist). • Die Prämie wird immer gezahlt. 2006 Pearson Education, Inc. All rights reserved. 4.9 Verwechseln von Gleichheits- (==) und Zuweisungsoperator (=) 66 • L-Werte (L-values) – Ausdrücke, die auf der linken Seite einer Zuweisung stehen können – Können verändert werden (d.h. verfügen über eigenen Speicherplatz, wie Variablen) • Beispiel: x = 4; • R-Werte (R-values) – Können nur auf der rechten Seite einer Zuweisung stehen – Konstanten, z.B. Zahlen (d.h. 4 = x; ist nicht möglich ) • L-Werte können als R-Werte benutzt werden, aber nicht umgekehrt. 2006 Pearson Education, Inc. All rights reserved. 67 Tipp zur Fehlervermeidung Normalerweise schreiben Programmierer Bedingungen wie x == 7 mit dem Variablennamen auf der linken und der Konstanten auf der rechten Seite. Wenn man es umgekehrt macht, wie in 7 == x, kann der Compiler eine Vertauschung von == und = als Fehler melden, da der Wert einer Konstanten (7) nicht durch eine Zuweisung geändert werden darf. Dies ist günstiger als ein logischer Fehler zur Laufzeit. 2006 Pearson Education, Inc. All rights reserved.