560 likes | 638 Views
EINI-I Einführung in die Informatik für Naturwissenschaftler und Ingenieure I. Vorlesung 2 SWS WS ‘99/00 Gisbert Dittrich FBI Unido dittrich@cs.uni-dortmund.de. Gliederung Kapitel 2. Elementare Daten- und Kontrollstrukturen: Je aus Beispielen entwickeln:
E N D
EINI-IEinführung in die Informatik für Naturwissenschaftler und Ingenieure I Vorlesung 2 SWS WS ‘99/00 Gisbert Dittrich FBI Unido dittrich@cs.uni-dortmund.de
Gliederung Kapitel 2 • Elementare Daten- und Kontrollstrukturen: Je aus Beispielen entwickeln: • In-/Decrement-Operatoren • Getchar • Bedingte Anweisung • Zuweisung • Disjunktion/Konjunktion • Switch - break - continue • Eindimensionale Felder • For-Schleife • Grammatikergänzung
Prog-4 Beispiel: Lesen und Testen • Problem: Lies Zeichen für Zeichen aus der Eingabe, bis das Endezeichen '@' erscheint. Gelesene Zeichen, die ungleich dem Leerzeichen sind, werden ausgegeben, sofern sie druckbar sind.
Ausführung des Blocks, falls die Bedingung wahr ist Test der Bedingung { cout << "Gelesen: " << c << endl; cin >> c; } Verlassen der while-Schleife, falls die Bedingung falsch ist Beispiel: Lesen und Testen cin >> c; while (c != Ende) { cout << "Gelesen: " << c << endl; cin >> c; }
Sprachelemente: Test, Negation • Der Test einer Bedingung hat den Wert wahr, falls das Resutat von 0 verschieden ist. Das Resultat mit dem Wert 0 wird stets als falsch interpretiert. • == ist Test auf Gleichheit • != ist Test auf Ungleichheit • Vergleich erfordert Übereinstimmung der Typen. • ! ist Negation in C++, d. h. man kann c !=Ende auch schreiben als !(c == Ende)
Sprachelemente: Zuweisung • = ist Zuweisung • a = b weista den Wert b zu (und gibt den Wert von b als Wert zurück: die Zuweisung hat einen Wert, ist also ein Ausdruck) • a == b überprüft, ob die Werte von a und b identisch sind. • Folgen von Anweisungen werden in {..} eingeschlossen und gelten als eine Anweisung.
Prog-5 Beispiel: Zeichen zählen • Erweiterung des vorigen Beispiels: • Möchte zusätzlich Zeichen zählen und die Anzahl der gelesenen Zeichen ausgeben. • Alle Zeichen werden auch ausgegeben.
Sprachelemente: Inkrementieren • ++Zaehler erhöht den Wert der Variablen Zaehler um 1 (ist also gleichwertig mit der Zuweisung Zaehler = Zaehler + 1) • Variante: Zaehler++ • ++Zaehlererhöht Zaehler um1und verwendet der erhöhten Wert (also: Erhöhung vor der Benutzung), • Zaehler++ verwendet den alten Wert von Zaehler und erhöht Zaehler dann.
Sprachelemente: Inkrementieren • ++Zaehlerheißt Präfix-, Zaehler++ heißt Postfix-Form Beispiel: a=1; b=1; c=1; d=1; cout << ++a << b++ << --c << d-- << ‘\n' << a << b << c << d; druckt: 2101 2200
Beispiel: Zeichen zählen 2 • Erweiterung: möchte zusätzlich Anzahl der Leerzeichen und die Anzahl der Zeilen kennenlernen. • c ist Leerzeichen genau dann, wenn c == ' ' • c beendet eine Zeile genau dann, wenn c == '\n' • Beachte: cin überliest die Leerzeichen, sucht also in der Eingabe nach dem ersten Zeichen , das vom Leerzeichen verschieden ist. Prog-6
Sprachelemente: getchar() • getchar: liest von der Tastatur das nächste Zeichen und gibt es als Wert zurück. • Technisch: getchar ist eine Funktion ohne Argument • Aufruf muß in C++ mit leerer Argumentliste erfolgen, also als getchar()
Sprachelemente: Bedingte Anweisung • Bedingte Anweisung (einfache Form): if (Bedingung) { Folge von Anweisungen} • Dabei Wirkung: • Auswertung des Ausdrucks "Bedingung" liefert: != 0 (d. h. wahr): Ausführung des Blocks { ... } • Auswertung des Ausdrucks "Bedingung" liefert: == 0 (d. h. falsch): Ignorieren/Auslassen des Blocks { ... }
Sprachelemente: Bedingte Anweisung • Vorsicht: In Bedingungen wird nicht auf wahr oder falsch getestet, sondern auf: != 0 / == 0 • Zudem: Wieso long int Zaehler (und nicht int Zaehler)? • Schutz vor Überlauf, falls der Wert INT_MAX überschreitet.
Sprachelemente: Bedingte Anweisung • Besteht die Folge nur aus einer Anweisung, so können die Klammern { ... } entfallen: double f = 1.0; if (f) cout << "Bingo!" druckt Bingo!
Beispiel: Wörter zählen • Erweiterung zu Vorigem: • Möchte zusätzlich wissen, wie viele Wörter der Text enthält. • Wörter? • Getrennt durch Leerzeichen, Zeilenenden oder Tabulatoren.
Prog-7 Beispiel: Wörter zählen • Also: wenn beim Lesen von c gilt:c == ' ' || c == '\n' || c == '\t' so bin ich nicht in einem Wort. • Das merke ich mir; ich merke mir auch, wenn ich ein Wort neu betrete (; dann erhöhe ich den Wortzähler).
Beispiel: Wörter zählen Zeilenende gesehen while (c != Ende) { if (c == ZeilenEnde) ZeilenZaehler++; if (c == LeerZeichen || c == ZeilenEnde || c == Tab) ImWort = false; else if (!ImWort) { ImWort = true; ++WortZaehler; } c = getchar(); ++Zaehler; Trenner gesehen keinen Trenner gesehen, also in einem Wort nächstes Zeichen erhöhe Zähler
Sprachelemente: Zuweisung • Die Zuweisung WortZaehler = 0 • weist der Variablen WortZaehler den Wert 0 zu • hat den Wert 0 (d. h. den zugewiesenen Wert) • Die Zuweisung wirkt also nicht nur als Anweisung (, die etwas tut), sondern auch als Ausdruck (, die einen Wert hat).
Sprachelemente: Zuweisung • Die mehrfache Zuweisung Zaehler = Wortzaehler = 0 wirkt wie Zaehler = (Wortzaehler = 0) • Also: • Auswertung der Zuweisung Wortzaehler = 0 • Zuweisung des resultierenden Werts an die Variable Zaehler
Sprachelemente: Zuweisung • Auswertung erfolgt also von rechts nach links • a = b = c ist gleichwertig mit a = (b = c) („rechtsassoziativ“). • Konsequenz: der Wert kann weiterverwendet werden. • z.B. a + (b = 3) bewirkt:: • Zuweisung von 3 an die Variable b, • Erhöhung von a um 3, • das ist häßlich !!.
Sprachelemente: Zuweisung • Beispiel: Testen: • if ((c = getchar( )) == Ende): Lies das nächste Zeichen, weise es c als Wert zu und (,da dies auch wie ein Ausdruck wirkt, ) teste den Wert von c, etc. • Das trägt heftig zur Unlesbarkeit mancher Programme bei!
Sprachelemente: Disjunktion • || ist der „oder“ - Operator („Disjunktion“) , dabei ist: x == y || a == b || e == fgleichwertig mit (x == y || a == b) || e == f(„linksassoziativ“)
Sprachelemente: Disjunktion • Auswertung nur solange, bis das Ergebnis feststeht !! Beispiel: • if ( a = = b || e = = (k = r + 1)) cout << k a b r k e Druck 0 1 17 0 18 18 0 0 17 0 18 0 • Analog: && Konjunktion („und“- Operator) beliebte Fehlerquelle !
Sprachelemente: Bedingte Anweisung • Bedingte Anweisung mit Alternative. Syntaktisch sieht sie so aus: if (Bedingung) { Folge_1 } else { Folge_2 }
Sprachelemente: Bedingte Anweisung • Folge_1, Folge_2 sind Folgen von Anweisun-gen • Bedeutung: klar. • Falls die Folge nur aus einer einzigen Anwei-sung besteht, kann { } weggelassen werden. • Diese Anweisungen können wieder eine be-dingte Anweisung sein (wie im Programmtext) • Folge_1 wird ausgeführt, wenn die Bedingung wahr, Folge_2 wird ausgeführt, wenn die Bedingung falsch ist
if (Bed_1) { Folge_1 } else if (Bed_2) { Folge_2 } else { Folge_3 } Sprachelemente: Bedingte Anweisung wird ausgeführt, wenn Bed_1 wahr ist • Mehrgliedrige Variante wird ausgeführt, wenn Bed_1 falsch, jedoch Bed_2 wahr ist Bitte besonders beachten ! wird natürlich in allen übrigen Fällen ausgeführt
Sprachelemente: Bedingte Anweisung • Knifflig: if1 (Bed_1) if2 (Bed_2) { Folge_1 }else { Folge_2 }Wohin gehört das else? Zu if1 oder zu if2? Ausprobieren!
Sprachelemente: switch-case Beispiel: Programmausschnitt switch (c) { case 'A': ++Zaehler_A; case 'B': ++Zaehler_B; case 'C': ++Zaehler_C; default: ++Zaehler_sonst; } Vorsicht: Abschließen Vorsicht: Abschließen Vorsicht: Abschließen
switch-case Sprachelemente: switch-case-break Beispiel: Programmausschnitt switch (c) { case 'A': ++Zaehler_A; break; case 'B': ++Zaehler_B; break; case 'C': ++Zaehler_C; break; default: ++Zaehler_ sonst; }
Sprachelemente: switch-case-break • switch(x)prüft Wert von x gegen Werte const in: • caseconst: Dabei gilt: • Werte müssen verschieden sein • Werte müssen vom Typ von x sein • Achtung: Typkonvertierungen beachten ! • können über Ausdrücke berechnet werden • zugehörige Anweisungsfolge abschließen • z.B. durchbreak • ansonsten werden die nachfolgenden Fälle mit durchlaufen!!
Sprachelemente: switch-case-break • break • bewirkt Sprung z.B. aus switch, while, for. • default • deckt alle nicht aufgeführten Fälle ab. • kann fehlen.
Prog-8 Beispiel: Wörter etc. zählen • Problem: Möchte wissen, wie oft die folgendenZeichen vorkommen: • Ziffern (pro Ziffer: wie oft?) • Trennzeichen (d. h. '\t', '\n', ' ‘) • alle anderen
Felder Anzahl der Elemente in dem Feld • int ZiffernZaehler[10];vereinbart ein Feld mit Namen ZiffernZaehler • das Feld enthält die ganzzahligen Elemente ZiffernZaehler[0]..Ziffernzaehler[9] Ende bei Anzahl-1 Beginn bei 0 (immer!)
Felder • Konstruktionsmuster: • TT Ara[k] stellt ein Feld Ara mit k ElementenAra[0], ..., Ara[k-1] zur Verfügung, jedes Feldelement ist vom Grundtyp TT • im Augenblick ist der Grundtyp int • k kann ein ganzzahliger Ausdruck sein, der zur Zeit der Definition des Feldes bekannt sein muß.
Anmerkungen • c - '0' : • Konvertiert implizit c in eine ganze Zahl: das Bitmuster wird als Zahl interpretiert, ebenso '0'. • Ergibt: '8'-'0' = 8 • Die Konversion wird durch - ausgelöst. (Operatoren der Subtraktion müssen Zahlen sein). • Ziemlich unsauber, aber Teil der Magie von C++.
Anmerkungen • Bei ++ZiffernZaehler[c - '0'] passiert also folgendes: • der Wert der zu c gehörenden Ziffer wird ermittelt, der entsprechende Feldeintrag wird um 1 erhöht. • c muß einer Ziffer entsprechen • es hätte auch ZiffernZaehler[c - '0']++ heißen können.
Die for-Schleife Initialisierungs- teil Bedingungs- teil Aktionsteil • for (A; B; C) { Folge von Anweisungen} • A - Initialisierungsteil: Mit diesem Wert wird die Folge von Anweisungen am Anfang durchlaufen, (falls B erfüllt). • z. B. Zuweisung eines Anfangswerts an die "Laufvariable". Schleifenrumpf
Die for-Schleife • B:Bedingungsteil: wird vor jedem Durch-lauf überprüft. Wenn die Auswertung den Wert falsch ergibt: Abbruch/Verlassen der Schleife Wenn die Auswertung den Wert wahr ergibt: Ausführung des Schleifenrumpfs und des Aktionsteils (C). - C: Aktionsteil: wird bei jedem Durchlauf ausgeführt.
Beispiel 1: for-Schleife • for (i = 0; i < 10; i++) ZiffernZaehler[i] = 0; initialisiert alle Elemente des Feldes ZiffernZaehler zu 0 • Gleichwertige Formulierung: for (i=0; i<10;) ZifferZaehler[i++]=0;
Beispiel 2: for-Schleife Initialisierungsteil leer Aktionsteil leer for (;(c=getchar())!=Ende;) cout <<c; ist gleichwertig mit c=getchar(); while (c!=Ende){ cout << c;c=getchar(); } Überprüfung findet statt
Beispiel 3: for-Schleife • A, B oder C können leer sein: "Preis"frage: for (;;); tut was ? Endlosschleife, die nichts tut
break Beispiel 4: for-Schleife-break for (;;) { cin >> c; if (c >= '0' && c <= '9') break; else ++Zaehler; }
continue Beispiel 5: for-Schleife-continue for (i=1;i < 11;i++) { cin >> c; if (c >= '0' && c <= '9') continue; ++Zaehler; }
Beispiel 5: for-Schleife-continue • continue • läßt den Rest des Rumpfes weg • springt an den Anfang des nächsten Durchlaufs
Grammatikergänzung Kapitel 2 • Expressions expression: assignment-expression /* additive --> assignment- */ more assignment-expression: conditional-expression unary-expression assignment-operator assignment-expression assignment-operator: = more constant-expression: conditional-expression conditional-expression: logical-or-expression more logical-or-expression: logical-and-expression logical-or-expression | | logical-and-expression
Grammatikergänzung Kapitel 2 • Expressions logical-and-expression: inclusive-or-expression logical-and-expression & & inclusive-or-expression inclusive-or-expression: equality-expression more equality-expression: relational-expression equality-expression == relational-expression equality-expression != relational-expression relational-expression:additive expression more
Grammatikergänzung Kapitel 2 • Expressions additive-expression: multiplicative-expression additive-expression + multiplicative-expression additive-expression - multiplicative-expression multiplicative-expression: unary-expression multiplicative-expression * unary-expression multiplicative-expression / unary-expression multiplicative-expression % unary-expression /* primary-expression --> unary-expression*/ unary-expression: primary expression ++ unary-expression more
Grammatikergänzung Kapitel 2 • Expressions primary-expression: literal more ( expression ) name literal: integer-constant character-constant floating-constant string-literal boolean literal boolean literal: false true
Grammatikergänzung Kapitel 2 • Statements statement: labeled-statement expression-statement compound-statement selection-statement iteration-statement jump-statement more labeled_statement: more case constant-expression : statement default : statement
Grammatikergänzung Kapitel 2 • Statements expression-statement: expressionopt ; /* ; !!!!!*/ compound-statement:{ statement-seqopt } [statement-seqopt = statement-seq | l ] statement-seq: statement statement-seq statement selection-statement: if ( condition ) statement if (condition ) statementelsestatement switch (condition ) statement condition: expression more