Übersicht

Werbung
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
Übersicht
3.1 Die Bibliotheksfunktion scanf() I
3.15 Die switch-Anweisung - Beispiel
3.2 Die Bibliotheksfunktion scanf() II
3.16 Die switch-Anweisung – Bemerkungen zum
Beispiel
3.3 Vergleichsoperatoren
3.4 Beispiele mit Vergleichsoperatoren
3.5 Logikoperatoren
3.6 Beispiele mit Logikoperatoren
3.7 Ausdrücke mit unterschiedlichen Operatoren
3.8 Bedingter Ausdruck
3.9 Die if-Anweisung
3.10 Die if-Anweisung – Beispiel 1
3.11 Die if-Anweisung – Beispiel 2
3.12 Die if-Anweisung – Beispiel 3
3.13 Die if-Anweisung – Beispiel 4
3.14 Die switch-Anweisung
Prof. Martin Trauth
Folie 1 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.1 Die Bibliotheksfunktion scanf() I
Die Funktion scanf() ist sozusagen das Gegenstück zu printf(): sie liest Werte von der Standard-Eingabe (das ist bei PCs
die Tastatur) und weist sie Variablen zu.
Syntax:
scanf(<Formatstring>, <Variable/n>)
Beispiele:
int int1;
double doublevar1;
Modifikator l (long), weil Variable den Typ double hat
scanf(“%i“, &int1)
scanf(“%lf“, &doublevar1)
Im Gegensatz zu printf() besteht der Formatstring (string = Zeichenkette) üblicherweise nur aus Platzhaltern.
Die Platzhalter haben folgende Syntax: %[*][MaxZeichen][Modifikator]Typ
Die Typzeichen entsprechen denen für printf(), ebenso die optionalen Modifikatoren.
Die Option * führt dazu, dass nur eingelesen, aber dieser Wert keiner Variablen zugewiesen wird.
MaxZeichen gibt eine maximale Zeichenanzahl des eingelesenen Werts an.
Prof. Martin Trauth
Folie 2 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.2 Die Bibliotheksfunktion scanf() II
In den Beispielen steht jeweils ein & vor den eigentlichen Variablennamen. Das hat damit zu tun, dass die Funktion die
Werte der Variablen ändern soll (printf tat das nicht) und wird später noch genauer erläutert.
scanf() muss wissen, wann die Eingabe per Tastatur beendet ist. Die Eingabe muss daher mit der „Wagenrücklauftaste“
(Return oder CR) beendet werden. Oft (aber nicht immer) hat die Enter-Taste am Ziffernblock die gleiche Funktion.
Der Programmablauf wird so lange gestoppt bis alle von scanf() erwarteten Werte eingegeben sind.
Einen eventuell erwünschten Programmabbruch erreicht man mit strg-C (cntrl-C), d.i. gleichzeitiges Drücken der Tasten
Strg und C.
Hinweis:
Man kann mit scanf() auch mehrere Werte einlesen (z.B. durch Leerzeichen getrennt). Das empfiehlt sich aber nur in
Ausnahmefällen, denn jeder Benutzereingabe sollte immer eine Erklärungszeile vorangehen welche Eingabe nun
erwartet wird (Ausgabe der Erklärungszeile per printf()). Sonst sieht der Benutzer nur, dass das Programm nicht weiter
geht und weiß nicht warum.
Bei mehreren Werteingaben hintereinander verliert der Benutzer evtl. die Übersicht.
Professionelle Programme (wenn sie etwas taugen) prüfen außerdem stets ob eine Benutzereingabe überhaupt gültig ist
und der Benutzer nicht etwa tzrgl eingegeben hat, wo eine Ganzzahl erwartet wurde...
scanf() ist eher für einfache Anwendungen zu gebrauchen, wo man sich auf die Eingabequalität verlassen kann.
Prof. Martin Trauth
Folie 3 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.3 Vergleichsoperatoren
Mit Vergleichsoperatoren werden die Werte zweier Operanden miteinander verglichen. Abhängig vom Ergebnis dieses
Vergleichs ist der Vergleichsausdruck wahr oder falsch.
C arbeitet nicht mit einzelnen Bits. Wahr (true) und falsch (false) werden daher nicht mit Bits sondern mit
Zahlenwerten dargestellt:
0 steht für falsch
Jeder andere Zahlenwert (auch negative Zahlen) steht für wahr.
Das Ergebnis von Vergleichsoperationen ist entweder 0 oder 1 (Typ int)
Die Vergleichsoperatoren in C (beziehen sich immer auf die Zahlenwerte der Operanden):
Op1 < Op2
Op1 kleiner Op2
Op1 > Op2
Op1 größer Op2
Op1 <= Op2
Op1 kleiner oder gleich Op2
Op1 >= Op2
Op1 größer oder gleich Op2
Op1 == Op2
Op1 gleich Op2 (nur Wertevergleich – keine Zuweisung!)
Op1 != Op2
Op2 ungleich Op2
Prof. Martin Trauth
Folie 4 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.4 Beispiele mit Vergleichsoperatoren
3<x
Wahr, wenn x größer als 3 ist. Bei x= 3,001 wäre das z.B. schon der Fall.
a>c
Wahr, wenn der Wert von a größer als der Wert von c ist.
48 <= ‘0‘
Wahr, denn der Zahlenwert des Zeichens 0 ist 48 (s. ASCII-Tabelle).
‘A‘ <= ‘a‘
Wahr, denn Großbuchstaben haben kleinere Zahlenwerte als Kleinbuchstaben.
‘M‘ == ‘m‘
Falsch
‘0‘ != 0
Wahr
‘\0‘ != 0
-0.348 < -0.3
1 == 1.0
Falsch
Wahr
Wahr, denn es kommt nur auf die Zahlenwerte an, nicht auf den Datentyp
Prof. Martin Trauth
Folie 5 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.5 Logikoperatoren
Um Logikoperationen durchführen zu können stellt C die elementaren Logikoperatoren UND (AND), ODER (OR)
und NICHT (NOT) zur Verfügung.
Die Logikwerte wahr und falsch werden durch Zahlenwerte „ungleich 0“ (wahr) und 0 (falsch) dargestellt.
Die Logikoperatoren in C:
Op1 && Op2
Op1 UND Op2
Op1 & Op2
bitweise Op1 UND Op2
Op1 || Op2
Op1 ODER Op2
Op1 | Op2
bitweise Op1 ODER Op2
!Op1
NICHT Op1
~Op1
bitweise Negation von Op1
Op1^Op2
bitweises EX-OR (exklusives ODER)
! (NICHT) hat die höchste Priorität unter den Logikoperatoren, gefolgt von && und || .
Für bitweise Verarbeitung gilt die gleiche Reihenfolge.
Ansonsten werden Reihenfolgen binärer Operatoren (solche mit 2 Operanden) von links nach rechts
ausgewertet.
Prof. Martin Trauth
Folie 6 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.6 Beispiele mit Logikoperatoren
3 && x
Wahr, wenn x nicht 0 ist.
0xAB73 & 0xFF00
1 || x
Immer wahr.
0xAB73 | 0xFF00
Hat das Ergebnis 0xAB00, da die einzelnen Bits UND-verknüpft werden
0 || x
Wahr, wenn x nicht 0 ist.
Hat das Ergebnis 0xFF73, da die einzelnen Bits ODER-verknüpft werden
!k
Wahr (1), falls k = 0, sonst falsch (0)
!(a || b)
Falsch (0), wenn entweder a oder b wahr ist (oder beide). Das ODER wird zuerst ausgewertet (Klammer!).
~ 0xFF00
!0
Hat das Ergebnis 1 (wahr)
Hat das Ergebnis 0x00FF, da alle Bits „umgedreht“ werden. Aus 1 wird 0, aus 0 wird 1.
0xAB73 ^ 0xFF00
Hat das Ergebnis 0x5473. Das Ex-OR hat dann wahr (1) als Ergebnis wenn nur eins
von beiden Bits 1 ist. Sind beide 0 oder beide 1, dann ist das Ergebnis falsch
(entsprechendes Ergebnis-Bit ist 0)
Hinweis: bitweise Logikoperationen erfordern Operanden von Typ unsigned integer (positive Ganzzahlen), um gut
interpretierbare Ergebnisse zu erhalten.
Prof. Martin Trauth
Folie 7 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.7 Ausdrücke mit unterschiedlichen Operatoren
Man kann in C sehr komplexe Ausdrücke bilden, da man arithmetische, Vergleichs- und Logikoperatoren fast
unbegrenzt kombinieren kann.
Beispiel:
2. * pi <= winkel1 || umfang – 10. == 5.3 && freigabe15
Wie in der Mathematik werden Teilausdrücke in Klammern zuerst bearbeitet. Bei verschachtelten Klammern werden
zuerst die innersten Klammern ausgewertet.
Neben den bereits erwähnten Prioritäten, wie der Punkt-vor-Strich-Regel bei Arithmetikoperatoren, gelten folgende
Prioritäten in absteigender Reihenfolge:
1.
sog. unitäre Operatoren, die nur auf einen Operanten wirken (z.B. !)
2.
Arithmetikoperatoren
3.
Vergleichsoperatoren (<, >, <= und >= haben höhere Priorität als == und !=)
4.
Logikoperatoren
5.
Zuweisungen
In dem Beispiel oben werden also zuerst die arithmetischen Operationen 2. * pi und umfang – 10. ausgeführt. Danach
folgen die Vergleiche (<= und ==), dann die UND-Verknüpfung (&&) und zum Schluss das ODER (||). Das Ergebnis des
Ausdrucks ist also ein Logikwert (1 oder 0). Falls dieser Wert einer Variablen zugewiesen werden sollte, würde das noch
folgen. Empfehlung: Klammern verwenden wegen Übersichtlichkeit.
Prof. Martin Trauth
Folie 8 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.8 Bedingter Ausdruck
Der bedingte Ausdruck verwendet einen Logikausdruck für eine Entscheidung.
Syntax:
<Logikausdruck> ? <1. Ausdruck> : <2. Ausdruck>
Beispiel:
resultat = x > y ? a + 309 : c – 5.5
Funktion:
Wenn der Ausdruck links vom Fragezeichen wahr ist, wird der 1. Ausdruck rechts davon als Ergebnis (Wert des
Gesamtausdrucks) verwendet, wenn er falsch ist der 2. Ausdruck. Der Doppelpunkt trennt die beiden Ausdrücke.
Beispiel für eine typische Anwendung:
printf(“Die Versandkosten betragen %.2f Euro“, warenwert >= 100. ? 0. : 5.);
Wenn der Warenwert (in Variable warenwert) größer oder gleich 100. ist, dann wird die 0. an Stelle des Platzhalters in
der printf()-Funktion gesetzt. Ist er kleiner 0., dann wird die 5. verwendet.
Der bedingte Ausdruck ist die einfachste Form von Verzweigungen in C-Programmen.
Prof. Martin Trauth
Folie 9 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.9 Die if-Anweisung
Die if-Anweisung ist sehr vielseitig und flexibel. Sie wird daher für die Programmierung von Verzweigungen
(Entscheidungen) in C am meisten verwendet.
Syntax:
if (<Logikausdruck 1>)
<Anweisung 1 (oder Block1)>
else if (<Logikausdruck 2>)
<Anweisung 2 (oder Block 2)>
...
else if (<Logikausdruck n>)
<Anweisung n (oder Block n)>
else
<Alternativ-Anweisung (oder Block)>
Prof. Martin Trauth
Folie 10 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.10 Die if-Anweisung – Beispiel 1
Ein Programmabschnitt als Beispiel:
if (warenwert >= 1000.) { // wenn Warenwert mindestens 1000 Euro
fracht = 0.; // keine Frachtkosten
bonus = 50.; // Bonus 50 Euro
}
else if (warenwert >= 500.) { // wenn Warenwert mindestens 500 Euro
fracht = 0.; // keine Frachtkosten
bonus = 0.; // aber auch kein Bonus
}
else { // bei kleinerem Warenwert
fracht = 10.; // 10 Euro Frachtkosten
bonus = 0.;
}
Der erste Logikausdruck in einer if..else if..else-Kette der wahr ist, führt zur Abarbeitung der entsprechenden Anweisung
oder eines Blocks von Anweisungen (eingefasst in geschweifte Klammern). Nur diese Anweisung oder dieser Block
werden ausgeführt. Danach wird das Programm hinter dem if...else if...else-Abschnitt fortgesetzt.
Prof. Martin Trauth
Folie 11 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.11 Die if-Anweisung – Beispiel 2
Die else if- und else- Abschnitte sind optional, d.h. sie können auch entfallen. Ein Beispiel mit reinem if-Block, das
zum gleichen Ergebnis führt wie Beispiel 1.
bonus = 0; // Anfangswert setzen
fracht = 10.
if (warenwert >= 1000.) // wenn Warenwert mindestens 1000 Euro
bonus = 50.; // Bonus 50 Euro
if (warenwert >= 500.) // wenn Warenwert mindestens 500 Euro
fracht = 0.; // keine Frachtkosten
Dieses Programm ist kompakter, aber weniger übersichtlich. Man muss schauen wo und warum die Anfangswerte
überschrieben werden.
Da den if-Anweisungen nur einzelne Anweisungen folgten, wurden keine Blöcke in geschweiften Klammern benötigt.
Hinweis: direkt nach dem Logikausdruck in der if-Anweisung folgt noch kein Semikolon, denn die Anweisung ist noch
nicht „komplett“ ohne die nachfolgende Anweisung.
Prof. Martin Trauth
Folie 12 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.12 Die if-Anweisung – Beispiel 3
Man kann if-Anweisungen schachteln, d.h. die Anweisung in einem if-Block ist wieder eine if-Anweisung.
bonus = 0; // Anfangswert setzen
fracht = 10.
if (warenwert >= 500.) { // wenn Warenwert mindestens 500 Euro
fracht = 0.; // keine Frachtkosten
if (warenwert >= 1000.) // wenn Warenwert mindestens 1000 Euro
bonus = 50.; // 50 Euro Bonus
}
Das zweite if befindet sich innerhalb eines Blocks, da auf das erste if zwei Anweisungen folgen: die Zuweisung von 0. an
die Variable fracht und die zweite if-Anweisung. Die einzelne Anweisung hinter dem zweiten if benötigt keinen Block.
Man könnte aber auch einen Block mit nur einer Anweisung schreiben. C erlaubt das.
Auch innerhalb von else if- oder else-Blöcken können neue if- else if- else-Anweisungen stehen.
Hinweis:
Durch geeignetes Plazieren der geschweiften Klammern und Einrücken von Programmzeilen sollte immer deutlich
gemacht werden, welche Anweisungen zu einer if- else if- else-Konstruktion gehören.
Prof. Martin Trauth
Folie 13 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.13 Die if-Anweisung – Beispiel 4
Hier ein Beispiel für einen fehlerhafte Programmtext mit if-Anweisung
if (warenwert >= 500.) { // wenn Warenwert mindestens 500 Euro
fracht = 0.; // keine Frachtkosten
if (warenwert >= 1000.) // wenn Warenwert mindestens 1000 Euro
bonus = 50.; // 50 Euro Bonus
}
else {
bonus = 0;
fracht = 10.
}
Eigentlich gut gedacht: statt des Setzens von Anfangswerten wird die Zuweisung der Werte von fracht und bonus im
Falle „Warenwert unter 500 Euro“ in einen else-Block verlegt. Das macht den Programmtext strukturierter. Aber es
wurde etwas übersehen:
Bei Warenwerten zwischen 500 (inklusive) und 1000 wird die innere if-Anweisung nicht ausgeführt (weil Logikausdruck
falsch). Auch der else-Block wird nicht ausgeführt, da dieses else nur zur äußeren if-Anweisung gehört. Die Variable
bonus ist daher nicht definiert. Wenn sie später verwendet wird, hat sie sehr wahrscheinlich unsinnige Werte.
Prof. Martin Trauth
Folie 14 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.14 Die switch-Anweisung
Die switch-Anweisung ist eine weitere Möglichkeit Fälle zu unterscheiden und das Programm zu verzweigen. Sie
verwendet keine Logikausdrücke sondern Zahlenwerte (Ganzzahlen) zur Entscheidung.
Syntax:
switch (<Ganzzahlausdruck>) {
case <Ganzzahlkonstante 1> :
Switch benötigt immer einen Block.
<Anweisung(en)>
case <Ganzzahlkonstante 2> :
<Anweisung(en)>
...
Die Doppelpunkte kennzeichnen die caseSchlüsselworte als Marken (labels).
Gleiches gilt für die defaut-Marke.
case <Ganzzahlkonstante n> :
<Anweisung(en)>
default:
<Anweisung(en)>
}
Ende des Switch-Blocks.
Funktion: der Programmablauf verzweigt zu der case-Marke, deren Zahlenwert dem Ganzzahlausdruck nach switch
entspricht. Paßt keiner der Zahlenwerte, dann wird zur default-Marke verzweigt.
Die default-Marke ist optional, man kann sie also auch weglassen.
Prof. Martin Trauth
Folie 15 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.15 Die break-Anweisung
Wenn die switch-Anweisung zu einer Marke verzweigt hat, läuft das Programm von dort aus bis zum Ende des switchBlocks weiter. Das ist oft unerwünscht, denn dann werden auch alle die Anweisungen ausgeführt, die hinter den
folgenden case-Marken stehen. Auch die Anweisungen hinter der default-Marke würden ausgeführt.
Will man das vermeiden, dann setzt man break-Anweisungen hinter die Anweisungen, die nur zu einer caseAlternative gehören. Die break-Anweisung bewirkt, dass das Programm den switch-Block verlässt und dahinter
weitergeführt wird.
Syntax:
break;
Hinweis:
Die break-Anweisung wird nicht nur im Zusammenhang mit switch verwendet, sondern ist vielseitiger. Sie unterbricht
stets einen bestimmten Vorgang.
Prof. Martin Trauth
Folie 16 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.16 Die switch-Anweisung – Beispiel
/* Beispiel für Switch-Anweisung, switch1.c */
/* Das Programm berechnet die Tage in einem Monat*/
Fortsetzung:
case 4:
#include <stdio.h>
case 6:
case 9: case 11:
main() {
int jahr, monat, tage;
tage = 30;
printf("\nBitte Jahr eingeben: ");
break;
default:
scanf("%i", &jahr);
tage = 31;
printf("\nBitte Monat eingeben: ");
scanf("%i", &monat);
} // Ende switch-Block
if (monat >= 1 && monat <= 12 && jahr > 1582) {
printf("\n%i hat der %i. Monat %i Tage\n", jahr,
monat, tage);
switch (monat) {
} // Ende if-Block
case 2:
else
if (!((jahr%100)%4) && (jahr%100) || !(jahr%400))
tage = 29; // Schaltjahr!
else
printf("\nFalsche Datumseingabe!");
}
tage = 28;
break; // switch-Block verlassen
Prof. Martin Trauth
Folie 17 / 19
Informatik 1 – Teil 3: Vergleichen, Logikoperatoren, Verzweigungen
3.17 Die switch-Anweisung – Bemerkungen zum Beispiel
Der Ausdruck (monat >= 1 && monat <= 12 && jahr > 1582) in der 1. if-Anweisung stellt sicher, dass nur gültige
Monate (in Zahlen) und Jahre nach der gregorianischen Kalenderreform eingegeben werden.
Der etwas komplizierte Ausdruck (!((jahr%100)%4) && (jahr%100) || !(jahr%400)) des zweiten if ermittelt die
Schaltjahre. Dazu werden diverse Teilbarkeiten überprüft (nach den Regeln von Papst Gregor).
Die Fälle der Monate 4, 6, 9 und 11 münden alle über die entsprechenden case-Marken in die Anweisung tage= 30;
Danach wird mit break; der switch-Block verlassen.
Allgemeiner Hinweis zur Verwendung der switch-Anweisung:
Sie funktioniert auch mit einzelnen Buchstaben, da diesen (ganze) Zahlenwerte zugeordnet sind. Eine case-Marke kann
also z.B. lauten: case ‘B‘:
Genauso hätte man schreiben können: case 66:
denn 66 ist der ASCII-Zahlenwert des Zeichens B.
Prof. Martin Trauth
Folie 18 / 18
Herunterladen