FB Informatik Prof. Dr. R.Nitsch Programmieren 1 - Grundlagen Reiner Nitsch Homepage mit Skript und Materialien zu PG1: www.fbi.h-da.de/~r.nitsch Was geschieht beim Ausführen eines Programms FB Informatik Prof. Dr. R.Nitsch Ein Programm ist eine Datei, die Befehle enthält, die der Computer ausführen kann. Wird eine ausführbare Datei (.exe) gestartet, wird sie zunächst von der Festplatte in den Hauptspeicher geladen. Nur dort kann das Programm gestartet werden. werden die Befehle vom Prozessor (CPU) abgearbeitet. Ein gestartetes Programm nennt man Prozess. Die CPU besitzt einen Programmzeiger der auf die Stelle zeigt, die als Nächstes bearbeitet wird. Beim Starten des Prozesses wird dieser Zeiger auf den ersten Befehl des Programms gesetzt. Jeder Befehl weist die CPU an, Datenwerte aus dem Speicher zu lesen zu schreiben oder zu berechnen. Datenwerte in Speicherstellen zu vergleichen und in Abhängigkeit davon mit der Abarbeitung an einer anderen Stelle fortzufahren. Die Befehle, die von der CPU derart interpretiert werden, bilden den Befehlssatz der Maschinensprache dieser CPU. Der Hauptspeicher enthält sowohl die Befehle als auch die Daten Die Befehle und die Datenwerte sind binär kodiert Die verschiedenen Prozessoren unterscheiden sich im Umfang ihrer Befehlssätze und in den Binärcodes für die einzelnen Befehle. Deshalb laufen Programme auch nur auf dem Prozessor, dessen Befehlssatz bei der Erstellung des Programms verwendet wurde. 24.03.2011 C++ Grundlagen 2 Programmiersprachen - Machschinensprachen FB Informatik Prof. Dr. R.Nitsch Muttersprache des jeweiligen Prozessors Definiert durch sein Hardwaredesign (total maschinenabh.) besteht aus aufeinanderfolgenden Bits Für Menschen schwer nachvollziehbar Für Programmierzwecke völlig ungeeignet Höhere Programmiersprachen sind besser geeignet. Beispiel: Code B17D41C3 B18D41C7 4FCA472A DC7E23BA 24.03.2011 Kommentar Lade Wert in Adresse 41C3 in Reg. 1 Lade Wert in Adresse 41C7 in Reg. 2 Addiere die Registerinhalte und speichere das Ergebnis in Reg. 1 Speichere Inhalt von Register 1 unter der Speicheradresse 23BA C++ Grundlagen 3 Programmiersprachen - Assembler-Sprachen FB Informatik Prof. Dr. R.Nitsch Die "Useability" von Maschinensprache ist gleich Null. Bessere Useability hat die Assemblersprache, die sich 1:1 in Maschinensprache übersetzen läßt. Das Übersetzungsprogramm wird Assembler genannt. Jeder CPU hat ihre eigene Assemblersprache. Beispiel: LOAD R1, LOAD R2, ADD R1, STORE R1, #41C3h #41C7h R2 #23BAh Assembler B17D41C3 B18D41C7 4FCA472A DC7E23BA Für Menschen leichter merkbar und lesbar Ideal für zeitkritische Algorithmen durch optimale Ausnutzung des Befehlssatzes Hohe Speicherplatzökonomie Total maschinenabhängig Ungeeignet für größere Softwareprojekte 24.03.2011 C++ Grundlagen 4 Programmiersprachen - Hochsprachen FB Informatik Prof. Dr. R.Nitsch fassen mehrere Maschinenbefehle zu Anweisungen (statements) zusammen benutzen Elemente der Alltagssprache und bekannte mathematische Notationen Beispiel: int number1, number2, sum; sum = number1 + number2; Anweisung 1 Anweisung 2 Anweisungen werden von Compilern bzw. Interpretern in Maschinencode übersetzt. Für Menschen leicht versteh- und anwendbar Maschinenunabhängig Weit verbreitete Hochsprachen sind (C, C++, Java, Fortran, Cobol, ...) 24.03.2011 C++ Grundlagen 5 Der Algorithmus FB Informatik Prof. Dr. R.Nitsch Anders als ein Mensch hat ein Computer keine Fantasie und keine Erfahrungen. Die Programmbefehle müssen ihm zwingend vorschreiben, was er tun soll, und dabei keine Missverständnisse zulassen. Alle Voraussetzungen müssen ausformuliert werden. Eine solche Verfahrensbeschreibung nennt man einen Algorithmus Es ist schwieriger als man denkt, ein Verfahren so zu beschreiben, dass der Ausführende zwingend zu einem bestimmten Ergebnis kommt. Beispiel: Kochrezept für ein 3-Minuten-Ei: Lege ein Ei für 3 Minuten in kochendes Wasser. Wie lautet die Befehlsfolge für einen Computer oder Menschen ohne Erfahrung und Fantasie? 24.03.2011 C++ Grundlagen 6 Algorithmus für 3 min Ei FB Informatik Prof. Dr. R.Nitsch nehme ein Ei. nehme einen Kochtopf mit 23 cm Durchmesser und Höhe 12 cm. nehme einen Wasserhahn nehme eine Herdplatte und schalte sie auf Stufe 3 nehme 1 l Wasser aus dem Wasserhahn und fülle damit den Kochtopf. Stelle den Kochtopf auf die Herdplatte. solange Wassertemperatur im Kochtopf kleiner 100° tue nichts. lege Ei in Kochtopf. merke dir die aktuelle Zeit als Startzeit. solange aktuelle Zeit kleiner Startzeit plus 3 min tue nichts. schalte Herdplatte aus. Nimm Ei heraus. 24.03.2011 C++ Grundlagen 7 Das erste Programm: Simulation der Arbeitslosigkeit /31-43/ FB Informatik Prof. Dr. R.Nitsch Jedes C++ Programm muss genau eine Funktion 'main' enthalten Beim Programmstart sucht der Computer die Funktion 'main' und beginnt dort mit der Ausführung. int main() { // Keine Anweisungen, d.h. arbeitslos! } Es bedeuten: int main () {} /*...*/ //... 24.03.2011 Platzhalter für ganze Zahl zur Ergebnis-Rückgabe C++ Schlüsselwort für Hauptprogramm Innerhalb dieser Klammern können dem Hauptprogramm Informationen mitgegeben werden. Block (enthält die Anweisungen an den Rechner) Kommentar, der über mehrere Zeilen gehen kann Kommentar bis Zeilenende C++ Grundlagen 8 Der C++ Klassiker: Die Begrüßung // File: HelloStudis.cpp #include <iostream> using namespace std; FB Informatik Prof. Dr. R.Nitsch // Macht dem Computer die Ein- und Ausgabefunktionen zugänglich // iostream: Name einer C++ Header-Datei // Diese Zeile zunächst immer hinter die #include-Zeilen schreiben. // Erklärung folgt später. // This program outputs the message "Hallo Studis!" to the monitor int main() // All C++ programs start by executing the function main { // Ausgabe: cout (Abkürzung für "character out") ist die Standardausgabe zum Monitor. // Der Doppelpfeil deutet an, dass alles, was rechts davon steht, zur Ausgabe cout gesendet wird. cout << "Hallo Studis!\n"; // output "Hallo Studis!" (ohne "") Steuerzeichen für "neue Zeile" (später mehr) Zeichenkette (string literal). Die Begrenzerzeichen (") werden nicht ausgegeben. return 0; } Unser Programm läuft einwandfrei; es gibt daher 0 zurück. Diese Anweisung kann fehlen, dann wird automatisch 0 zurückgegeben. // Ein ';' schliesst jede Anweisung (statement) und jede Definition ab 24.03.2011 C++ Grundlagen 9 Vom Quellcode zum Objektcode /31/ FB Informatik Prof. Dr. R.Nitsch C++ ist eine Compilersprache: d.h. zuerst muss ein C++ Compiler den Programmcode in für den Computer verständliche Sprache übersetzen. Quellcode (.cpp) g++ -c HelloStudis.cpp 24.03.2011 Compiler Objektcode (.obj) compilieren (HelloStudis.obj wird erzeugt) (bzw. HelloStudis.o bei anderen Compilern) C++ Grundlagen 10 Vom Objektcode zum ausführbaren Programm FB Informatik Prof. Dr. R.Nitsch Ein Programm besteht meist aus mehreren Teilen (translation units) Beispiel: "Hallo Studis!" besteht aus Hauptprogramm "main" und dem Header "iostream" Jedes Teil wird separat compiliert Die verschiedenen Objectcode-Dateien müssen durch ein weiteres Programm, den Linker, miteinander zum ausführbaren Programm verknüpft werden. HelloStudis.o Linker HelloStudis.exe Libraries (.o) Beispiel: g++.exe -o hellostudis.exe hellostudis.o lib1.o ... binden. Das Programm wird durch Eintippen von hellostudis.exe gestartet 24.03.2011 C++ Grundlagen 11 Integrated Development Environment (IDE) /37/ FB Informatik Prof. Dr. R.Nitsch Integrierte Entwicklungsumgebung (IDE) Editor Quellcode (.cpp) Header (.h) Präprozessor Übersetzen in Maschinencode Compiler Objektcode (.obj) Linker Standard-Bibliothek Bibliotheken Binden der Objektdateien Ausführbare Datei (.exe) Debugger Schnelleinstieg in Microsoft Visual C++ Express 2008 siehe Anhang Loader RAM 24.03.2011 C++ Grundlagen 12 Der Präprozessor und der Compiler und der Fehlerteufel FB Informatik Prof. Dr. R.Nitsch Präprozessor bereitet den Quellcode für den Compiler vor wird u.a. gesteuert durch Präprozessor-Anweisungen die mit '#' beginnen Die Anweisung #include <EineDatei> bzw. #include "EineDatei" fordert den Präprozessor auf, diese Anweisung durch den Inhalt der Datei mit Namen EineDatei zu ersetzen. Entfernt Kommentare aus Quellcode Der Compiler achtet auf korrekte Syntax und Grammatik ist dabei sehr pingelig, beschwert sich selbst über kleinste Details, hat aber immer Recht. Beispiele für häufige Fehler: #include fehlt Tippfehler (z.B. im Namen der Include-Datei) Fehlendes " im String-Literal integer statt int < statt << oder = statt == ' statt " ... 24.03.2011 C++ Grundlagen 13 Systematische Programmentwicklung FB Informatik Prof. Dr. R.Nitsch Wie werden Programme entwickelt? Schritt 1: Analysis Schritt 2: Design Schritt 3: Implementation Schritt 1: Analysis - Formulierung der Aufgabe (aus Benutzersicht) -> OOAD Beispiel: Addition zweier Zahlen 1. Das Programm fordert den Benutzer auf, 2 Zahlen einzugeben 2. Benutzer gibt 2 Zahlen auf der Tastatur ein 3. Das Programm liest die Zahlen und berechnet die Summe 4. Das Programm gibt die Summe auf dem Bildschirm aus Schritt 2: Design - Zerlegung der Aufgabe in Teilaufgaben -> OOAD Beispiel: Addition zweier Zahlen Ausgabe des Prompts "Gib 2 Zahlen ein: " Lies 2 Zahlen in 2 Variablen summand1 und summand2 ein Die Summe beider Zahlen berechnen und in Variable summe speichern summe auf dem Monitor ausgeben: "Summe = <Ergebnis>" 24.03.2011 C++ Grundlagen 14 Systematische Programmentwicklung FB Informatik Prof. Dr. R.Nitsch Schritt 3: Implementation - Umsetzen der Teilaufgaben in C++ Code Die Kommentare bleiben zur Dokumentation erhalten // Datei: summe.cpp // Die erste Zeile dokumentiert den zugehörigen Dateinamen. #include <iostream> using namespace std; int main() { // Addition zweier Zahlen int summe; // Definition von Variablen: Weist den Compiler an, int summand1; // (1) Speicherplatz zu reservieren, int summand2; // (2) diesem Speicherplatz einen Namen (z.B. summe) zu geben. // Variablennamen sind symbolische Adressen für Speicherbereiche // Ausgabe des Prompts "Gib 2 Zahlen ein: " cout << "Gib 2 Zahlen ein: "; // Benutzeraufforderung (prompt) // Zeichenkette mit Anführungszeichen als Anfangs- und Ende-Kennung 24.03.2011 C++ Grundlagen 15 Systematische Programmentwicklung FB Informatik Prof. Dr. R.Nitsch // Lies 2 Zahlen in 2 Variablen summand1 und summand2 ein cin >> summand1; Hier werden zwei Werte von der Tastatur eingelesen! cin >> summand2; // Eingabe: Der Doppelpfeil zeigt hier in Richtung des Objekts, das ja von der Tastatur einen neuen // Wert auf nehmen soll. Die Information fließt von der Eingabe cin zum Objekt a beziehungsweise b. // Die Summe beider Zahlen berechnen und in Variable summe speichern summe = summand1 + summand2; // Zuweisung: Das Ergebnis der Addition auf der rechten Seite wird der Variablen auf der linken // Seite des Gleichheitszeichens zugewiesen, d.h. das Ergebnis wird in den Speicherplatz // "summe" kopiert. // summe auf dem Monitor ausgeben: "Summe = <Ergebnis>" cout << "Summe= " << summe; return 0; // Unser Programm läuft einwandfrei; es gibt daher 0 zurück. // Diese Anweisung kann fehlen, dann wird automatisch 0 zurückgegeben. } 24.03.2011 C++ Grundlagen 16 Genauer hingeschaut: Speicherkonzept bei Variablen FB Informatik Prof. Dr. R.Nitsch Variablen (Speicherbereiche für Werte) müssen vor erster Benutzung definiert werden sind u.a. gekennzeichnet durch Namen (symbolische Adresse), Datentyp (type), Adresse im Speicher und Wert (value) ihre Adresse referenziert das erste Byte des Speicherbereichs für den Wert schreibender Zugriff überschreibt (löscht) den bisherigen Wert cin >> summand1; // Angenommen Benutzer gibt 5 ein cin >> summand2; // Angenommen Benutzer gibt 6 ein summe = summand1 + summand2; // Addition und Zuweisung Lesender Zugriff verändert den aktuellen Wert nicht cout << summe; Adresse Name 10123 summand1 10124 summand2 10125 summe 24.03.2011 C++ Grundlagen Wert ? 5 ? 6 11 ? 17 C++ Namenskonventionen FB Informatik Prof. Dr. R.Nitsch Funktions-, Variablen- und andere Namen (Bezeichner) unterliegen der folgenden Konvention: Ein Bezeichner besteht aus einer Folge von Buchstaben, Ziffern und Unterstrich (_). beginnt stets mit einem Buchstaben oder einem Unterstrich. dürfen nicht mit den vordefinierten Schlüsselwörtern /673/ übereinstimmen (zum Beispiel for, int, main...). kann prinzipiell beliebig lang sein. In den Compilern ist die Länge jedoch begrenzt, zum Beispiel auf 31 oder 255 Zeichen. sollte unbedingt selbsterklärend sein. sollte nicht mit '_' oder '__' beginnen (wird systemintern benutzt) Achtung: C++ unterscheidet zwischen Groß- und Kleinschreibung (ist case-sensitive) Beispiele int int int int 1_summand; summand 1; summand1; summand_1; 24.03.2011 falsch! (Ziffer am Anfang) falsch! (Name enthält Leerzeichen) richtig! AndereMöglichkeit: richtig! C++ Grundlagen 18 Syntaxgraph für Bezeichner FB Informatik Prof. Dr. R.Nitsch Syntaxgraphen erlauben eine sehr kompakte Darstellung der Syntaxregeln. Die Regeln werden eingehalten solange man den Linien in Pfeilrichtung folgt. Dabei stößt man auf ovale oder kreisförmige Felder, sogenannte Terminale. Diese sind elementar, d.h. sie können nicht weiter verfeinert werden. rechteckige Felder, sogenannte Nichtterminale. Diese Syntaxbestandteile bedürfen noch der näheren Beschreibung, z.B auch durch einen Syntaxgraphen oder im Text. Beispiel: Syntaxdiagramm für Namen Buchstabe _ a 0 Buchstabe b 1 Ziffer : z 2 A 9 _ B : Syntaxdiagramm für Namen : Syntaxdiagramme für Ziffer und Buchstabe Z 24.03.2011 C++ Grundlagen 19 Nocheinmal: Programm "Addition zweier Zahlen" FB Informatik Prof. Dr. R.Nitsch Diskussion: Was geschieht bei Eingabefehlern? Eingabe: Eingabe: Eingabe: Eingabe: 1 2.0 1 3.9 2.5 2 eins zwei Ausgabe Ausgabe Ausgabe Ausgabe 3 4 4206638 2028688046 Wie ist dieses Verhalten zu erklären? Erklärung folgt! 24.03.2011 C++ Grundlagen 20 Eingabe und Typ FB Informatik Prof. Dr. R.Nitsch Eigenschaften des Eingabeoperators >> Die Eingabeoperation >> ("get from") ist type-sensitiv R1: Führende Zwischenraumzeichen (ZRZ; engl. whitespace) werden ignoriert. Zwischenraumzeichen sind Leerzeichen ' ', Tabulatorzeichen '\t', Zeilensprung '\v', Seitenvorschub '\f' und Zeilenendekennung '\n'. Andere Zeichen werden entsprechend dem Ziel-Datentyp interpretiert. R2: Die Entnahme von Zeichen endet R2a: mit dem ersten ZRZ (ZRZ = Endekennung der Eingabe = Normalfall) bzw. R2b: mit dem ersten nicht "passenden" Zeichen int summand1=0; int summand2=0; std::cin >> summand1; std::cin >> summand2; Eingabe 1 1.0 2\n 2\n 24.03.2011 summand1 int: summand1: 0 summand2: 0 summand2 Ausgabe Kommentar 1 2 3 R1 und R2a 1 0 1 int-Variable bestehen nur aus Ziffern. R2b: Lesen stoppt bei '.' ".0 2\n" bleibt im Puffer C++ Grundlagen 21 Was lernen wir daraus? FB Informatik Prof. Dr. R.Nitsch Erkenntnis 1: Variable sollten initialisiert werden. Erkenntnis 2: Ein Tool zum schrittweisen Ausführen des Programms erleichert die Fehlersuche -> Debugger Bedienung des Debuggers: siehe Anlage Erkenntnis 3: Das Verhalten des Operators '>>' ist typ-sensitiv Erkenntnis 4: Programme/Algorithmen stellen Vorbedingungen an den Input, damit sie richtig funktionieren. Diese Preconditions (PRE) sollten vom Programm überprüft werden oder zumindest in einem Kommentar dokumentiert sein. 24.03.2011 C++ Grundlagen 22 Wiederholung der wichtigsten Begriffe FB Informatik Prof. Dr. R.Nitsch Begriffe: Objekt: Ein Speicherbereich zum Ablegen von Datenwerten (eines bestimmten Typs) Typ: legt fest welche Art von Information im Objekt abgelegt werden kann und legt fest was mit dem Objekt gemacht werden kann. Beispiel: Ganzzahlen (2, 7) können multipliziert werden, Zeichenketten ("Hallo", "Welt") nicht. Datenwert: Menge von Bits, die entsprechend dem Typ interpretiert werden. Variable: ist ein benamtes Objekt Variablen-Deklaration: Anweisung, die dem Compiler den Namen eines Objekts und den Typ dieses Objekts bekannt macht.. Variablen-Definition: Weist den Compiler an, Speicherplatz für ein Objekt vorzusehen. Eine Definition schliesst die Deklaration mit ein. Beispiele: age: Zeichenketten werden in string-Variablen abgelegt. Ganzzahlen werden in int-Variablen abgelegt. Gleitkommazahlen werden in float-Variablen abgelegt. 24.03.2011 C++ Grundlagen int: 42 Adresse: 10123 Objekt vom Typ int mit Namen age, das den Ganzzahl-Wert 42 enthält! 23 C++ Standarddatentypen für Variablen FB Informatik Prof. Dr. R.Nitsch int: summand1: ? int: summand2: 100 int summand1; int summand2 = 100; string name = "Annemarie"; string: name: : Annemarie Ganzahl-Variable ohne Anfangswert Ganzahl-Variable mit Anfangswert Zeichenketten-Variable mit Anfangswert C++ ist typsicher, d.h. Variable akzeptieren keine Werte vom falschen Typ: // Fehler: 39 ist kein string // Fehler: "Annemarie" ist kein int string name = 30; int summand1 = "Annemarie"; C++ stellt viele Datentypen bereit. Die wichtigsten sind int number_of_steps double flying_time char decimal_point string name bool is_even = = = = = 30; 3.5; '.'; "Annemarie"; true; // int für Ganzzahlen // double für Gleitkommazahlen // char für Zeichen // string für Zeichenketten // bool für logische Variable Später mehr dazu! Literale: jeder Typ hat seinen eigenen Stil! Gleitkommazahlen approximieren das mathematische Konzept reeller Zahlen! 24.03.2011 C++ Grundlagen 24 Übungsaufgabe: Rechteckfläche berechnen FB Informatik Prof. Dr. R.Nitsch Implementieren Sie ein Programm RectangleArea.cpp, das den Benutzer Länge und Breite eines Rechtecks eingeben lässt und das daraus die Fläche berechnet und auf dem Monitor ausgibt. Hinweis: Benutzen Sie summe.cpp als Ausgangspunkt und passen Sie den Code an. 24.03.2011 C++ Grundlagen 25 Ausgabe-Formatierung mit Escape Sequenzen /54/ FB Informatik Prof. Dr. R.Nitsch cout << "Hallo Studis\n"; Escape Zeichen '\' kündigt Steuerzeichen für Ausgabe an. \n positioniert Cursor am Anfang der nächsten Zeile (newline) \t bewegt Cursor zum nächsten Tabstop \r Cursor zum Zeilenanfang ohne Zeilenvorschub \a erzeugt Hinweiston \\ gibt backslash '\' aus \" gibt Anführungszeichen aus … es gibt noch mehr cout << "Diese Zeichenkette enthaelt \"Anfuehrungsstriche\"." erzeugt diese Ausgabe auf Bildschirm: 24.03.2011 Diese Zeichenkette enthaelt "Anfuehrungsstriche". C++ Grundlagen 28 Formatierte Ausgabe mit Manipulatoren /373-376/ FB Informatik Prof. Dr. R.Nitsch Der Operator << wandelt automatisch die internen Datenformate in eine Textdarstellung um und gibt diese formatiert auf dem Bildschirm aus. Die Formatsteuerung übernehmen Flags in cout. Ein Flag ist ein Merkmal, das entweder vorhanden ist ( Flag ist gesetzt) oder nicht vorhanden ist ( Flag ist nicht gesetzt) . Die voreingestellten Formatierungsregeln (linksbündig, Feldweite 0, +-Zeichen unterdrückt, 10er Zahlenbasis) können angepasst werden, indem sog. Manipulatoren in den Ein-/Ausgabestrom eingefügt werden (z.B. << hex). 1_07 1_07- -OutputFormatting OutputFormatting Beispiele zur Formatierung von Ganzzahlen cout cout cout cout cout cout << << << << << << showpos << 166 <<endl; noshowpos << 166 endl; hex << 166 << endl; uppercase << 166 << endl; 166 << endl; nouppercase << dec << 166 << endl; 24.03.2011 // Ausgabe // Ausgabe // Ausgabe // Ausgabe // Ausgabe // Ausgabe C++ Grundlagen +166 166 a6 A6 A6 Wirkung persistent (=anhaltend) 166 29 Formatierte Ausgabe von Gleitpunkzahlen Formatierte Ausgabe mit Manipulatoren FB Informatik Prof. Dr. R.Nitsch Beispiele zur Formatierung von Gleitkommazahlen cout cout cout cout cout cout cout cout cout cout cout cout cout << << << << << << << << << << << << << 4./3 << endl; 3./2 << endl; setprecision(3); 4./3 << endl; 3./2 << endl; 4./2 << endl; showpoint ; 4./2 << endl; 3./2 << endl; noshowpoint; 3./2 << endl; 333. << endl; 3333. << endl; cout << fixed; cout cout cout cout cout cout << << << << << << 4./3 << endl; 3./2 << endl; 6.1234567e17 << scientific; 4./3 << endl; 3./2 << endl; // Ausgabe 1.33333 (Voreingestellte Genauigkeit: 6 Stellen) // Ausgabe 1.5 (Überflüssige Nullen unterdrückt) // Genauigkeit 3 Ziffern (#include <iomanip>) // Ausgabe 1.33 (Beachte: Keine 3 Nachkommastellen // Ausgabe 1.5 (Überflüssige Nullen unterdrückt) // Ausgabe 2 // Dezimalpunkt mit abschließenden Nullen erzwingen // Ausgabe 2.00 // Ausgabe 1.50 // Ausgabe 1.5 // Anzeige 333 // Anzeige 3.33e+003 (Stellenzahl zu groß -> autom. Exponentialschreibweise) // Dieses "Autom. mixed Format" ist Standardeinstellung // Nie Ausgabe in Exponentialschreibweise. // Eingestellte Genauigkeit bestimmt die Zahl der Nachpunktstellen // Ausgabe 1.333 // Ausgabe 1.500 endl; // Ausgabe 612345670000000000.000 // Immer Ausgabe in Exponentialschreibweise // Ausgabe 1.333e+000 // Ausgabe 1.500e+000 cout.unsetf(ios::floatfield); // wieder autom. mixed Format (geht nicht anders!) 24.03.2011 C++ Grundlagen 30 Steuerung der Feldbreite, Ausrichtung und Füllzeichen Formatierte Ausgabe mit Manipulatoren FB Informatik Prof. Dr. R.Nitsch Beispiele für die Steuerung der Feldbreite, Ausrichtung und Füllzeichen cout << 166 << endl; cout << 1 << setw(5) << 166 << endl; cout << 1 << 166 << endl; cout << left << 1 << setw(5) << 166 << endl; cout << setfill('*') << setw(5) << 166 << endl; cout << right << setw(5) << 166 << endl; cout << internal << setfill('0') << showpos << setw(5) << 166 << endl; // Ausgabe 166 // Setzt Feldbreite einmalig (nicht anhaltend) auf 5 // Ausgabe 1 166 (Voreinstellung: rechtsbündig) // Ausgabe 1166 Jetzt wieder Feldbreite 0 (Standard) // Ausgabe 1166 (linksbündig) // '*' als Füllzeichen setzen (Voreinstellung: ' ') // Ausgabe 166** // wieder rechtsbündig // Ausgabe **166 // setzt Vorzeichen linksbündig und Wert rechtsbündig // Ausgabe +0166 cout.unsetf(ios::adjustfield); // internal zurücknehmen (geht nicht anders!) cout << setw(5) << 166 << endl; cout << setfill(' ') << setw(5) << 166 << endl; // Ausgabe 0+166 // wieder voreingestelltes Füllzeichen // Ausgabe +166 24.03.2011 C++ Grundlagen 31 Formatierte Eingabe von Zahlen Hausaufgabe FB Informatik Prof. Dr. R.Nitsch Schreiben Sie ein C++ Programm, das die folgende Ausgabe erzeugt Grad rad sin(x) cos(x) -------------------------------0.0 0.0 +0.000 +1.000 30.0 0.5 +0.500 +0.866 60.0 1.0 +0.866 +0.500 90.0 1.6 +1.000 +0.000 120.0 2.1 +0.866 -0.500 Tipps Sie müssen die Headerdatei <cmath> includieren. Bei http://www.cplusplus.com/reference/ wird die Anwendung der trigonometrischen Funktionen beschrieben! 24.03.2011 C++ Grundlagen 32 Einfache Datentypen und Operatoren FB Informatik Prof. Dr. R.Nitsch Ausdruck /44/ Ein Ausdruck besteht aus einem oder mehreren Operanden, die mit einander durch Operatoren verknüpft sind. Die Auswertung eines Ausdrucks resultiert in einem Wert, der an die Stelle desAusdrucks tritt. Ganzzahlen und ihre Operatoren /44-48/ Gleitkommazahlen und ihre Operatoren /48-52/ Konstante /52/ Zeichen /53-56/ logischer Datentyp bool /56/ Referenzen /57/ 24.03.2011 C++ Grundlagen 33 Ausgesuchte Operatoren Zuweisung Addition Verkettung Subtraktion Multiplikation Division Modulo (Rest) Inkrement um 1 Dekrement um 1 Inkrement um n Anhängen Dekrement um n Multiplizieren und zuweisen Dividieren und zuweisen Modulo und zuweisen Von s in x einlesen Von x nach s schreiben Gleich Nicht gleich Größer als Größer als oder gleich Kleiner als Kleiner als oder gleich 24.03.2011 FB Informatik Prof. Dr. R.Nitsch bool = char = + + int = double = string = + * / % ++ -+=n * / ++ -+=n += s>>x s<<x == != > >= < <= s>>x s<<x == != > >= < <= C++ Grundlagen -=n *= /= %= s>>x s<<x == != > >= < <= -=n *= /= s>>x s<<x == != > >= < <= s>>x s<<x == != > >= < <= 34 Implizite Typumwandlung ("casting") in den größeren Typ 5/2.0 und 5.5/2 sind ohne expliziten cast immer Gleitkommadivisionen. Begründung: C++ macht bei gemischten Ausdrücken automatisch einen Cast in den jeweils größeren Typ (s. Hierarchie der Typen). Beispiele: 5 / 2.0 int double x = 5/3 //danach x = 1.0 double int double int int double 'a'>'A' // Ergebnis: true weil 'a' 97 und 'A' 65 (ASCII) 2*( 'a'>'A' ) int true (1) 2 * 1 int i; i = '5'-'0'; 24.03.2011 FB Informatik Prof. Dr. R.Nitsch Hierarchie Hierarchie der der Typen Typen long long double double double double float float long long int int Aufzählungen Aufzählungen char char short short bool bool // Ergebnis: 2 2 // Ergebnis: 5 C++ Grundlagen Explizite Typkonvertierung 35 Implizites Casten in kleineren Typ bei Zuweisung implizit in kleineren Typ bei Zuweisungen double float int i; float x =3e9; i = 3.0 / 2; int double i = x; Hierarchie Hierarchie der der Typen Typen long long double double double double int // Compiler-Warnung: Verkürzung // von const double in int // 3e9 ist zu groß für int, Ergebnis undefiniert float float long long int int bool b = 3; int FB Informatik Prof. Dr. R.Nitsch bool char char short short bool bool 24.03.2011 C++ Grundlagen Explizite Typkonvertierung 36 Reelle Zahlen - Ungenauigkeitsprobleme /49/ FB Informatik Prof. Dr. R.Nitsch Numerische Auslöschung: Die Differenz float f = 1e8f, d; zweier fast gleich großer Werte wird 0, d = f + 4.0f; weil sich die signifikanten Ziffern cout << d - f << endl; Ausgabe: aufheben. 0 Überlauf (overflow) bei Division durch zu kleine Werte d = 1e23f / 1e-16f cout << d << endl; Ausgabe: 1.#INF Unterschreitung (underflow), wenn Ergebnis zu klein ist. d = 1e-23f/1e23f cout << d << endl; Ausgabe: 0 Ergebnisse können von der Reihenfolge der Berechnungen abhängen float k = 7.654321e-7, e = 1.0f,s1,s2; Ausgabe: s1 = k+e; 7.15256e-007 s1 = s1-e; // =k+e-e 7.65432e-007 s2 = k+e-e; cout << s1 << endl << s2 << endl; Achtung Bei sicherheitskritischen Berechnungen immer auf Genauigkeit achten. 24.03.2011 C++ Grundlagen 37 Wichtiger Unterschied: Zuweisung und Initialisierung a = 3; int a = 3; '=' ist der Zuweisungsoperator das Objekt a existiert hier schon, d.h. an anderer Stelle wurde für a Speicherplatz reserviert und es hat bereits einen Wert. Der vorhandene Wert muss erst gelöscht werden, bevor der neue Wert geschrieben wird. Dies geschieht bei der Ausführung (zur Laufzeit) des Programms 24.03.2011 FB Informatik Prof. Dr. R.Nitsch '=' ist keine Zuweisung sondern eine Definitionsanweisung Das Objekt existiert bis hierher noch nicht. Hier wird der Compiler angewiesen eine int-Variable zu erzeugen, also Speicherplatz für ein Ganzzahlobjekt zu reservieren und diesem den Namen a zu geben. Es ist noch kein Wert vorhanden, da der Speicherplatz noch nicht benutzt wurde. '=3' muss also keinen vorhandenen Wert löschen, bevor der neue Wert gesetzt wird. Die alles erledigt der Compiler, während er den Quellcode compiliert (zur Compilezeit). C++ Grundlagen 38 Regeln zum Bilden von Ausdrücken /41/ /59/ FB Informatik Prof. Dr. R.Nitsch a + b * c Punkt vor Strichrechnung (a + b) * c Klammern werden zuerst ausgewertet (von innen nach aussen) Auswertung von links nach rechts (linksassoziativ) a + b + c a * b * c Beispiel: mit Klammern: z = 2 * 3 % 4 + 6 / 2 - 5 1. z = 2. z = 2 + 6 / 2 - 5 3. z = 2 + 4. z = 5. z = 6. z = 0 24.03.2011 6 z = ((((2*3) % 4) + (6/2)) – 5) % 4 + 6 / 2 - 5 5 3 - 5 - 5 0 Ergebnis 0 in z speichern C++ Grundlagen Implizite Typkonvertierung 39 Vorrangtabelle für C++-Operatoren /862/ Priorität Operator 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. Assoziativität :: . -> [ ] ++ ("Postfix") -- ("Prefix") typeid() dynamic_cast<> static_cast<> const_cast<> reinterpret_cast<> sizeof f() (Fkt-Aufruf) ! ~ + ("unär") - ("unär") ++ ("Präfix") -- ("Präfix") & ("Adresse") * ("Verweis") new delete .* ->* * / % + ("binär") - ("binär") << >> < > <= >= == != & ("bitweises UND") ^ | && || ?: = += -= *= /= %= &= ^= |= <<= >>= throw , 24.03.2011 FB Informatik Prof. Dr. R.Nitsch C++ Grundlagen von links von rechts von links von links von links von links von links von links von links von links von links von links von links von rechts von rechts von rechts von links 40 Der Bedingungsoperator ?: /68/ FB Informatik Prof. Dr. R.Nitsch Ist der einzige Operator mit 3 Operanden ( ternärer Operator) Wählt einen von 2 Ausdrücken abhängig von Bedingung Syntaxdiagramm: Bedingung ? Ausdruck1 : Ausdruck2 ; Falls die Bedingung zutrifft ist der Wert des gesamten Ausdrucks der Wert von Ausdruck1, ansonsten der Wert von Ausdruck2 Beispiele: int zahl1 = -3, zahl2 = 5, min, max, betrag; min = zahl1 > zahl2 ? zahl2 : zahl1; // Ergebnis: min(zahl1,zahl2) max = zahl1 > zahl2 ? zahl1 : zahl2; // Ergebnis: max(zahl1,zahl2) betrag = zahl1 >= 0 ? zahl1 : -zahl1; // Ergebnis: abs(zahl1,zahl2) 24.03.2011 C++ Grundlagen Zuweisung 41 Benutzerdefinierte Datentypen /89/ FB Informatik Prof. Dr. R.Nitsch Häufig möchte man logisch zusammengehörige Daten zusammenfassen, die nicht vom selben Typ sind, z.B. die Personendaten Name (string), Alter (int), Gewicht (float) oder die Daten eines Punktes auf dem Monitor: seine x und y Koordinaten, seine Farbe und ob er sichtbar ist. Für diesen Zweck stellt C++ die Struktur als benutzerdefinierten Typ bereit Eine Struktur setzt sich zusammen aus beliebig vielen Elementen (auch Felder oder Komponenten genannt) beliebigen Typs. Syntaxdiagramm einer struct-Definition: struct Typname { Elemente } Variablenliste ; Beispiel: Struktur Punkt Definition der Struktur Point struct Point { int x; int y; bool isVisible; short colour; // 1=rot, 2=grün, 3=gelb } p; // p ist ein Punkt-Objekt 24.03.2011 C++ Grundlagen Anwendung der Struktur Point Point q; // q ist auch ein Punkt-Obj. // Zugriff auf Elemente p.x = 5; p.y = 10; p.colour = 1; p.isVisible = true; Punktoperator "." 42 Aufzählungstypen (Enumerations) /80/ FB Informatik Prof. Dr. R.Nitsch sind benutzerdefiniert bieten Unterstützung bei nicht-numerischen Wertebereichen Beispiele: Klassische Lösung Nachteile: int colour; // rot =0, grün =1, gelb =2 int wochentag; // Sonntag=0, Montag =1, usw. Syntaxdiagramm einer enum-Deklaration enum Typname { •Kommentar notwendig •nicht eindeutig: 0=rot oder 0=Sonntag •schlechte Lesbarkeit: if(farbe==2) … •Fehleranfällig: if(farbe==5)//Nicht definiert Werteliste Anwendung: } Variablenliste ; =0 =1 =2 // Werden intern wie int-Objekte gespeichert enum Colour { ROT, GELB, GRUEN }; // Typdeklaration Colour farbe = ROT; // Definition einer Variablen von diesem Typ enum Wochentag { SONNTAG, MONTAG, DIENSTAG, MITTWOCH, DONNERSTAG, FREITAG, SAMSTAG } heute, gestern; heute = MONTAG; gestern = SONNTAG; // Definition mit Initialisierung // Typname kann entfallen bei einmaliger enum { MOFA, LKW, PKW } fahrzeug; // Verwendung des Aufzählungstyps in // Variablendefinition (anonyme Typdef.) enum Muenzgeld { CENT=1, FUENFER=5, GROSCHEN=10 }; // Abweichende // Bewertungen 43 24.03.2011 C++ Grundlagen Aufzählungstypen - Goes&NoGoes FB Informatik Prof. Dr. R.Nitsch Für enum-Typen ist nur die Zuweisung definiert Für alle anderen Operationen wird vorher in int umgewandelt Beispiele: Wochentag heute, morgen; int i = sizeof(Wochentag); // i=4 heute = MONTAG; MONTAG = heute; // Fehler: MONTAG ist Konstante! i = heute; // richtig: Impliziter Cast in höheren Typ ist typsicher, weil Wert sich nicht ändert heute = i; // Fehler: Cast von int nach Wochentag nicht typsicher, da i Werte haben // kann, die Typ Wochentag nicht kennt heute = static_cast<Wochentag>(2); // so kann man den cast erzwingen (Pfui!) morgen = heute+1; // Warum geht das nicht? Was weiß das Anwendungssystem davon zur Laufzeit? NICHTS! Für jeden Aufzählungstyp legt der Compiler eine Symboltabelle an, mit der er die Symbole (z.B. ROT, GELB und GRUEN in die zugeordneten Ganzzahlwerte umwandelt. Im Maschinencode erscheinen nur diese Ganzzahlwerte. 24.03.2011 C++ Grundlagen 44 Programmstrukturierung /101 ff/ FB Informatik Prof. Dr. R.Nitsch Große Programme müssen in übersichtliche Teile zerlegt werden C++ stellt dazu mehrere Mechanismen bereit Funktionen Klassen Modulare Gestaltung (Bibliotheken) Funktionstemplates Namespaces 24.03.2011 C++ Grundlagen 45 Funktionen /102/ FB Informatik Prof. Dr. R.Nitsch Komplexe Aufgaben werden im Alltag nicht von einer Person allein bewältigt, sondern i.d.R. in Teilaufgaben geringerer Komplexität zerlegt und diese zur Lösung an verschiedene Personen delegiert (Prinzip "Teile und herrsche"). Zur Unterstützung dieses Prinzips stellt C++ u.a. Funktionen bereit. Funktionen sind eine Sequenz von Anweisungen (Anweisungsblock), mit eigenem Namen. Eine Funktion sollte immer nur E I N E abgeschlossende Teilaufgabe erledigen (Große Kohäsion). Die zur Aufgabenerledigung erforderlichen Daten werden der Funktion beim Aufruf mitgegegeben (Aktual-Parameter oder Argument). Das Ergebnis der erledigten Aufgabe liefert die Funktion an den Aufrufer (Auftraggeber) in Form eines Rückgabewertes (return value) zurück. Dieser tritt dann an die Stelle des Aufrufes. Beispiel: y=sin(x); Die Standard-Bibliothek enthält viele Funktionen, z.B. sqrt(), sin(), ... Daneben gibt es auch benutzerdefinierte Funktionen. Funktionen können selbst wieder Funktionen aufrufen. 24.03.2011 C++ Grundlagen 46 Globale benutzerdefinierte Funktion ohne Parameter #include <iostream> using namespace std; void main () { // show menu cout << "[1] Eingabe\n"; cout << "[2] Ausgabe\n"; cout << "[9] Fertig\n"; // … } Wird mehrmals im Programm verwendet. cut&paste Nachteile? void steht für "kein Rückgabewert" #include <iostream> using namespace std; void showMenu(); void main() { showMenu(); // … } Funktionsname besser mit Funktionsaufruf Funktionsdeklaration oder Funktionsprototyp Funktionsaufruf FB Informatik Prof. Dr. R.Nitsch • Die Funktionsdeklaration (Fkt-Prototyp) beschreibt das Funktionsinterface. Sie enthält für den Compiler alle erforderlichen Angaben (Typ, Reihenfolge und Menge der Ein- und Ausgabewerte), um den Funktionsaufruf übersetzen zu können. Merke: • Eine Funktion muss vor der ersten Benutzung deklariert aber nicht definiert sein. • Eine Funktion kann überall und beliebig oft deklariert werden. • Die Definition kann dann am Ende der Datei oder in einer ganz anderen Datei (z.B. Library) stehen. Funktionskopf void showMenu() { cout << "[1] Eingabe\n"; cout << "[2] Ausgabe\n"; cout << "[9] Fertig\n"; return; } 24.03.2011 Funktionsdefinition Funktionsrumpf • Die Funktionsdefinition (Implementierung) legt fest, wie die Funktion ihre Aufgabe erledigt. • In C++ können Funktionen nicht innerhalb anderer Funktionen definiert werden. • Eine Funktion darf nur einmal im Programm definiert werden. C++ Grundlagen 47 Globale Funktion mit Parametern und mit/ohne Rückgabewert #include <iostream> using namespace std; FB Informatik Prof. Dr. R.Nitsch Funktion Funktion gibt gibt Wert Wert vom vom Typ Typ double double zurück zurück double calcCircleArea( double ); Funktionsdeklaration Funktionsdeklaration Funktion Funktion benötigt benötigt zur zur Aufgabenerledigung Aufgabenerledigung 11 Funktionsparameter Funktionsparameter vom vom Typ Typ double double int main() { double r = 2.0; cout << calcCircleArea(r) << endl; return 0; Aufruf } Aufruf der der Funktion Funktion pie Ko Nach Nach Rücksprung Rücksprung wird wird hier hier der der Rückgabewert Rückgabewert eingesetzt. eingesetzt. Wertübergabe: Wertübergabe: Der Der Wert Wert der der Variablen r wird in die Variable Variablen r wird in die Variable radius radius der der Funktion Funktion kopiert. kopiert. double calcCircleArea(double radius ) { double area; area = 3.14 * radius * radius; return area; } 24.03.2011 Hier Hier Rücksprung Rücksprung zur zur Aufrufstelle. Aufrufstelle. Eine Eine Kopie Kopie von area wird zurück gegeben. von area wird zurück gegeben. C++ Grundlagen 48 Ablauf eines Funktionsaufrufs Beim Aufruf Speicherplatz belegen FB Informatik Prof. Dr. R.Nitsch … lokaler Parameter (z.B. area) Beim Rücksprung Speicherplatz wieder freigeben letzter Parameter Funktionsparameter … 1. Parameter (z.B. radius) Stack (Stapelspeicher) oder LIFO (Last In First Out) Rückgabewert hierher wird r kopiert hierher wird area kopiert Rücksprungadresse Reservierung von Speicherplatz auf dem Stapelspeicher (stack) für die FormalParameter. Initialisierung der Formal-Parameter mit den Aktual-Parametern (Argumenten). Speichern der Rücksprungadresse (= Stelle des Funktionsaufrufes im Programm) auf dem Stack und Fortsetzung des Programms am Anfang der aufgerufenen Funktion. Nach Ausführung der Funktion, Fortsetzung des Programms in der aufrufenden Funktion mit Hilfe der gesicherten Rücksprungadresse. Freigabe des belegten Stacks. 24.03.2011 C++ Grundlagen 49 Benutzung von Bibliotheksfunktionen #include <iostream> #include <cmath> using namespace std; FB Informatik Prof. Dr. R.Nitsch // Hinzufügen aller Funktionsdeklarationen der math-Library int main() { double x=1.5, y=2; y = sqrt(x); y = sin(x); // Argument x im Bogenmass y = sin(2); // auch ok! Typkonversion int → double y = sin(x+sqrt(2)); // Auch ok! Als Parameterwert darf auch ein beliebiger Ausdruck übergeben y = exp(x); // berechnet "10 hoch x" y = log(x); // natürlicher Logarithmus! y = log10(x); y = pow(x,2); // berechnet "x hoch 2" y = pow(x,"2"); // Fehler: Typumwandlung nicht möglich y = pow(x+3); // Aber Anzahl und Typ der Parameter müssen passen! return 0; } Woher weiß der Compiler Anzahl und Typ der erwarteten Parameter ? // cmath enthält die Deklaration double pow( double x, double y ); 24.03.2011 C++ Grundlagen 50 Prinzip der Trennung zwischen Schnittstelle und Implementierung FB Informatik Prof. Dr. R.Nitsch Wie? Nützliche Funktionen werden in einer separaten Datei (*.cpp) zu Bibliotheken zusammengefasst. Bibliotheken bündeln meist Funktionen eines Anwendungsbereichs (Grafik, Arithmetik, …) Die Funktionsdeklarationen einer Bibliothek werden in Headerdateien (*.h) zusammengefasst. Die Headerdateien werden bei Bedarf in die Anwendungen inkludiert. Die compilierten Bibliotheksdatei(en) (*.obj) werden dem Linker bekannt gemacht. Beispiel folgt! 24.03.2011 C++ Grundlagen 51 Prinzip der Trennung zwischen Schnittstelle und Implementierung Beispiel #include <iostream> using namespace std; Programm ludiert c n i d r wi #include "GeoLib.h" double calcCircleArea(double radius); int main() { double r = 2.0; cout << calcCircleArea(r) << endl; return 0; } double area; area = 3.14 * radius * radius; return area; 24.03.2011 // GeoLib.h Enthält alle Funktionsdeklarationen #pragma once // verhindert Mehrfachinkludierung double calcCircleArea(double radius); Schnittstelle Implementation double calcCircleArea(double radius ) { } FB Informatik Prof. Dr. R.Nitsch // GeoLib.cpp #include <iostream> using namespace std; // Implementierung double calcCircleArea(double radius) { double area; area = 3.14 * radius * radius; return area; } C++ Grundlagen 52 Vorteile der Trennung von Interface und Implementation FB Informatik Prof. Dr. R.Nitsch Bessere Wiederverwendbarkeit Kein Copy & Paste! Verbergen von Implementationsdetails (Kapselung) die der Anwender nicht zu kennen braucht, weil für ihn unwichtig die der Anwender nicht sehen soll (Schutz von "Know how", information hiding) Bessere Pflegbarkeit des Moduls: Implementation kann geändert werden ohne Auswirkung auf rufende Programme Höhere Zuverlässigkeit der Software Fertige Module sind (hoffentlich) gründlich getestet Getrennte Übersetzung möglich Module brauchen nur einmal in Objektdateien übersetzt zu werden, da sie sich i.d.R. nicht mehr ändern Die Objektdateien der Module werden dem Linker bekannt gemacht. Der Programmierer (des rufenden Programmes) braucht sich nicht um die Details der Implementation zu kümmern. 24.03.2011 C++ Grundlagen 53 Bestandteile eines C++ Programms FB Informatik Prof. Dr. R.Nitsch Bestandteile eines C++ Programms Kern von C++ Standardtypen Operatoren Kontrollstrukturen Klassen und Funktionen der Standardbibliothek Selbsterstellte Klassen und Funktionen und weitere Bibliotheken C++ kennt keine keine spezielle Syntax für Prozeduren. In C++ sind Prozeduren einfach Funktionen ohne Ausgabewert. 24.03.2011 C++ Grundlagen 54 HS-Übung 1 FB Informatik Prof. Dr. R.Nitsch Sie beginnen jetzt eine Geometrie-Bibliothek GeoLib zu erstellen. Sie soll Kreisfläche und Kreisumfang berechnen können. Für ¶ verwenden Sie ein Konstante. Schreiben Sie eine Anwendung, die den Nutzer zur Eingabe eines Radius auffordert und die Kreisflaeche ausgibt. Erweitern Sie GeoLib um die Fähigkeit, Flächen von Rechtecken zu berechnen. Die Anwendung fordert den Nutzer jetzt zusätzlich auch zur Eingabe von Länge und Breite auf und gibt die Rechteckflaeche aus. Auch Punkte sind geometrische Objekte. Ergänzen Sie GeoLib also um die Struktur Punkt. Für die Farbe verwenden Sie einen Aufzählungstyp mit Farben Rot, Gelb und Grün. Die Anwendung soll ein Punkt-Objekt erzeugen und anschliessend seine Koordinaten und Farbe ausgeben. 24.03.2011 C++ Grundlagen 55 HS-Übung 2 FB Informatik Prof. Dr. R.Nitsch Finden Sie die Fehler in den folgenden Programmfragmenten und erklären Sie, wie der Fehler behoben werden kann. a) int g(void) { cout << "in Funktion g\n"; int h(void){ cout << "in Funktion h\n"; } } c) void f(double a){ float a; cout << a << endl; } 24.03.2011 b) int sum( int x, int y){ int result ; result = x+y; } d) void product (void){ int a, b, c, ergebnis; cout << "Gib 3 Ganzzahlen ein: "; cin >> a >> b >> c; result = a * b * c; cout << "Ergebnis: << result << endl; return result; } C++ Grundlagen 56 Anweisungen FB Informatik Prof. Dr. R.Nitsch Programme enthalten Ausdrücke um Werte zu berechnen Programme benötigen zusätzlich die Möglichkeit, Werte wiederholt zu berechnen unter Alternativen auszuwählen Eingaben entgegenzunehmen und Ausgaben zu erzeugen Diese Dinge werden in vielen Programmiersprachen durch Anweisungen (Statements) erreicht. Bisher behandelte Arten von Anweisungen Deklarationsanweisung Ausdruck-Anweisung: Ein Ausdruck, gefolgt von einem Semikolon Wozu braucht man das Semikolon? Bespiel: es kann a=b ++ b; a=b ++; b; ist nicht eindeutig! gemeint sein, oder Auch cin >> i; ist eine Ausdrucksanweisung mit den Werten true: wenn Eingabe erfolgreich false: wenn Eingabe misslang. 24.03.2011 C++ Grundlagen a=b; a=b; ++b; ++b; a=b; ++ b; 58 Strukturen, die den Programmablauf kontrollieren FB Informatik Prof. Dr. R.Nitsch Kontrollstrukturen geben an in welcher Reihenfolge (Sequenz) ob (Auswahl) und wie oft (Wiederholung) Anweisungen ausgeführt werden, bzw. Anweisungen Anweisungen einfache einfache Anweisungen Anweisungen ob andere Programme aufgerufen werden (Aufruf von Funktionen) Sequenz Sequenz Lineare Kontrollstrukturen sind Kontrollstrukturen, die nur Sequenz, Wiederholung, Auswahl und Aufruf verwenden, aber keine Sprünge Strukturierte Programmierung Aufruf Aufruf Auswahl Auswahl Wiederholung Wiederholung Zur Erklärung wird neben dem Syntaxdiagramm eine Beschreibung auf höherer Sprachebene gewählt implementiert einen Algorithmus durch ausschließliche Verwendung einfacher Anweisungen und linearer Kontrollstrukturen 24.03.2011 lineare Kontrollstrukturen Kontrollstrukturen C++ Grundlagen Struktogramm Struktogramm (DIN (DIN 66261) 66261) Nassi-Shneiderman on the Web 59 Auswahlanweisung if ... else if Syntax-Diagramm Bedingung ( else FB Informatik Prof. Dr. R.Nitsch ) AnweisungOderBlock AnweisungOderBlock AnweisungOderBlock (AOB): Anweisung { } AnweisungOderBlock Struktogramm (DIN 66261) oder Nassi-Shneiderman-Diagramm Beispiele: if(Bedingung) if(Bedingung) AnweisungOderBlock1 AnweisungOderBlock1 wahr AOB1 AnweisungOderBlock2 AnweisungOderBlock2 B falsch AOB2 if(Bedingung) if(Bedingung) B falsch AnweisungOderBlock1 AnweisungOderBlock1 wahr else AOB1 AOB2 else AnweisungOderBlock2 AnweisungOderBlock2 AOB2 24.03.2011 AnweisungOderBlock1 wird nur ausgeführt, wenn Bedingung wahr ist (true oder ungleich 0) AnweisungOderBlock2 wird immer ausgeführt AnweisungOderBlock1 wird nur ausgeführt, wenn Bedingung wahr ist (true oder ungleich 0) AnweisungOderBlock2 wird nur ausgeführt wenn Bedingung falsch ist (false oder gleich 0) C++ Grundlagen 60 Beispiele if ... else Maximum-Funktion // Gibt maximum von a und b zurück int max( int a, int b ) { if(a>b) return a; else return b; } FB Informatik Prof. Dr. R.Nitsch Eingabe mit vorausgehender "Reinigung" if( !cin.good() ) { cin.clear(); // setzt alle Fehlerflags zurück cin.sync(); // löscht alle Zeichen im Eingabepuffer } int i; cin >> i; Eingabe mit nachfolgender Fehlerprüfung int i; cin >> i; if( cin.fail() ) { // prüft Fehlerflag cout << "Fehler: Eingabe misslungen!\n"; exit(1); // Beendet Programm; return value 1 // weist auf Fehler bei Ausführung hin } 24.03.2011 C++ Grundlagen 61 Mehr als 2 Alternativen FB Informatik Prof. Dr. R.Nitsch if ... else wählt aus 2 Alternativen eine aus Was, wenn aus mehr als 2 Alternativen zu wählen ist? Beispiel: Die signum-Funktion: sign(x) = 1 0 -1 Lösung: if ... else verschachteln w B1 w f B2 f w B3 f ABO1 ABO2 ABO3 ABO4 24.03.2011 x>1 x=0 x<0 C++ Implementierung von sign(x) ? if(B1) ABO1 else if(B2) ABO2 else if(B3) ABO2 else ABO4 C++ Grundlagen 62 Finden Sie die Fehler FB Informatik Prof. Dr. R.Nitsch if (a=b) { cout << "a ist gleich b"; if (x==1) if (y==1) cout << "x ist 1 und y ist 1"; else cout << "x ungleich 1"; Die switch-Anweisung wird später behandelt. 24.03.2011 C++ Grundlagen 63 Programmieren mit Vertrag FB Informatik Prof. Dr. R.Nitsch Vorbedingung (Precondidion): Der Zustand, in dem das System sein muss, damit die Funktion ihre Leistung erbringen kann. Nachbedingung (Postcondition): Beschreiben den Zustand, in dem das System sein muss, wenn die Leistung korrekt erbracht wurde. Für den Benutzer ist es unverzichtbar, diese Bedingungen zu kennen. Sie gehören verbal in die Funktionsdokumentation (siehe Beispiel unten) Für die Softwarequalität ist es oft unverzichtbar, die Vorbedingung zu prüfen Code, der Vorbedingung prüft und z.B. Abweichungen meldet (siehe Beispiel unten). Zumindest während der Testphase ist es unverzichtbar, die Nachbedingung zu prüfen. C++ assertions, die nur während der Debugphase ausgewertet werden (siehe Beispiel unten). double sqrt( double x ) { // Berechnet Quadratwurzel // PRE: x>=0 // POST: Maximaler Fehler kleiner 10-6 PRE&POST (mathematisch oder verbal) gehören zur Funktionsbeschreibung if( x>=0 ) { cout<< "Error in sqrt()"; //Aufrufer für korrekten Aufruf verantwortlich! exit(1); // Kontrollierter Programmabbruch, wenn Bedingung == false } // hier folgt der Algorithmus … assert( abs(y*y-x) < 1e-6 ); return y; } 24.03.2011 // Kontrollierter Programmabbruch, wenn Bedingung == false // #include <cassert> erforderlich! C++ Grundlagen 64 Wiederholungsanweisung while Syntax-Diagramm der while-Schleife while FB Informatik Prof. Dr. R.Nitsch ( Bedingung ) AnweisungOderBlock Solange die Bedingung wahr (true oder ungleich 0) ist, wird die Anweisung bzw. der Block ausgeführt. Anweisung oder Block Bedingung erfüllt? ja Die Bedingung wird zuerst geprüft. Ist sie zu Beginn unwahr, wird die Anweisung gar nicht erst ausgeführt abweisende Schleife Struktogramm Bedingung Anweisung oder Block nein while(true) { /*Anweisung(en)*/ } // unendliche Schleife while(false){ /*Anweisung(en)*/ } //Anweisungen werden nie ausgeführt 24.03.2011 C++ Grundlagen 65 Schleifenvariable FB Informatik Prof. Dr. R.Nitsch Zur Kontrolle der Wiederholungsrunden benötigt man eine Schleifenvariable Beispiel Schleifenvariable sv initialisieren solange Ausdruck unter Berücksichtigung von sv true ( ≠ 0) ist "Nutzleistung" Veränderung der sv Richtung Ziel Summation der Zahlen von 0 bis n int sum=0, sv=0, n; while( sv sum += sv; ++sv; } ) { Was hier steht, kann erst nach Definition des Veränderungsschritts festgelegt werden Veränderungsschritt Schleife für Grenzfälle prüfen: n = 0 ? n=1? Wiederholte Eingabe der Summanden durch Benutzer int sum=0, i=0; while( cin>>i ) { sum += i; } cout << sum << endl; 24.03.2011 // liefert true wenn Einlesen erfolgreich // Wie soll der Benutzer das Ende der Eingabe signalisieren? [Ctrl-Z] bedeutet Ende der Eingabe und setzt das "End-of-File"-Flag. cin.eof() gibt das EOF-Flag zurück (true, wenn gesetzt). cin.good() fragt alle Flags ab und ergibt true, wenn keins gesetzt ist. C++ Grundlagen 66 Die Anweisungen break und continue FB Informatik Prof. Dr. R.Nitsch Steuern den Kontrollfluß eines Programms break beendet unmittelbar while-, do-while-, for- und switch-Kontrollstruk-turen. Das Programm wird unmittelbar hinter diesen Strukturen fortgesetzt. continue in Wiederholungen beendet unmittelbar die Ausführung des zugehörigen Strukturblocks. Die Anweisungen hinter continue werden übersprungen und die Programmausführung mit der Bedingungsprüfung fortgesetzt. Beispiel für break Beispiel für continue void main() { int x=0; while (++x<10) { if ( x==5 ) break; cout << x << ' '; ++x; } cout << "Schleife verlassen bei x= " << x << endl ; } void main() { int x=0; while (++x<10) { if ( x==5) continue; cout << x << ' '; } cout << "Ausgabe der Zahl 5 mit" "continue verhindert!" << endl ; } 1 2 3 4 Schleife verlassen bei x= 5 1 2 3 4 6 7 8 9 Ausgabe der Zahl 5 mit continue verhindert! 24.03.2011 C++ Grundlagen 67 Häufige Programmierfehler in while-Schleifen FB Informatik Prof. Dr. R.Nitsch Finden und korrigieren Sie die Fehler in den nachfolgenden Programmsegmenten a) While ( c <= 5) { product +=c; ++c; b) while (z >= 0) sum += z; d) Der nachfolgende Programmcode soll die Werte 1…10 ausgeben! n = 1; while ( n < 10 ) cout << n++ << endl; c) x=1; while (x <= 10); x++; e) Die Zahlen 1..100 sollen addiert werden! f) int x=1, total=0; while (x<=100) total +=x; x++; while ( y > 0 ) { cout << y << endl; ++y; } g) int x=0; while (++x<10) { if ( x==5) continue; cout << x << ' '; } } Schleifenanweisungen mit for und do ... while werden später behandelt! 24.03.2011 C++ Grundlagen 68 HS-Übung 4: abweisende Schleife mit while FB Informatik Prof. Dr. R.Nitsch Schreiben Sie eine Funktion ggt die den größten gemeinsamen Teiler zweier Parametern vom Typ int bestimmt und zurück gibt. Testen Sie die Funktion mit einer Anwendung, die solange 2 Zahlen von der Tastatur einliest und den ggt ausgibt, bis eine der beiden Eingabezahlen 0 ist. Hinweis: Um 2 Bedingungen gleichzeitig zu testen, können Sie den logischen && Operator verwenden. Bsp: while ( payIn > 0 && payIn < 100 ) Lösung mit Pseudocode • Vorbedingung? Nachbedingung? • Schleifenvariable ggT mit Minimum beider Zahlen initialisieren • Prüfen, ob beide Zahlen ohne Rest durch ggT teilbar sind • Falls nein, ggT um eins vermindern • Falls ja, Schleife verlassen und mit nächster Anweisung fortfahren 24.03.2011 C++ Grundlagen Hausaufgabe 69 C++ Standardtyp vector FB Informatik Prof. Dr. R.Nitsch Im Alltag beschäftigen wir uns oft mit Tabellen: Bundesliga-, Gehalts-, Kalorien-, Noten-, Entfernungstabelle, Kontoauszug, Tilgungsplan, Kassenbon ... Der Standarddatentyp vector ist einfach eine Reihe von Elementen gleichen Typs. vector<int> v(6); // stellt 6 Elemente vom Typ int bereit, alle mit Anfangswert mit 0 vector<string> personal(5); // 4 Elemente vom Typ string bereit, alle initialisiert mit "" vector<double> vd(1000, -3.5); // vector mit 1000 doubles, alle mit Anfangswert -3.5 Auf die Elemente wird über eine Positionsangabe (Index) zugegriffen, d.h. das 1. Element hat Index 0, das Zweite Index 1 usw. v[0]=5; v[1]=7; v[2]=2; v[3]=8; v[4]=7; v[5]=3; size() v: 6 personal[0]="Karczewsky"; personal[1]="Hergenroether" personal[2]="Moore"; personal[3]="Nitsch"; v's Elements v[0] v[1] v[2] v[3] v[4] v[5] 5 7 2 8 7 3 v[5]="Lange"; personal[4]=007; // Fehler: Ein vector akzeptiert nur den vereinbarten Typ vd[20000] =4.2; // Laufzeitfehler: Kein Zugriff auf nicht existierende Elemente 24.03.2011 C++ Grundlagen 70 Wachstum ist auch für vector wichtig FB Informatik Prof. Dr. R.Nitsch vector ist ein dynamischer C++ Datentyp, d.h. er kann an Größe zulegen. vector<double> v; // Start als leerer vector ohne Elemente // Ausgabe: 0 cout<<v.size(); v.push_back(2.7); // 1 Element mit Wert 2.7 ans vector-Ende anhängen // Ausgabe: 1 cout<<v.size(); v.push_back(5.6); // 1 zweites Element mit Wert 5.6 hinzufügen // Ausgabe: 2 v.push_back(0.3); // 1 zweites Element mit Wert 5.6 hinzufügen // Ausgabe: 2 size() v: 0 size() v: 1 v[0] 2.7 size() v: 2 v[0] v[1] 2.7 5.6 size() v: 3 v[0] v[1] v[2] 2.7 5.6 0.3 size() und push_back() sind sogenannte Memberfunktionen von vector. Memberfunktionen lassen sich nur auf den Datentyp (hier: vector) anwenden, zu dem sie gehören. Ihre Definition wird im Zusammenhang mit Klassen behandelt. Ihre Aufrufsyntax unterscheidet sich von der gewöhnlicher Funktionen (siehe Beispiele oben): Sie werden über den '.'-Operator aufgerufen! 24.03.2011 C++ Grundlagen 71 Entfernen (löschen) des letzten Elementes FB Informatik Prof. Dr. R.Nitsch v.pop_back() ist eine Memberfunktion von vector genauso wie size(). Sie löscht das letzte Element aus dem Container v[2] = 0 v.pop_back() // hier wird nicht gelöscht, sondern dem Element // mit Index 2 ein neuer Wert zugewiesen // Das letzte Element wird gelöscht. Beachten Sie // dass size() nun um 1 reduziert ist! size() v: 3 v[0] v[1] v[2] 2.7 5.6 0.0 size() v: 2 v[0] v[1] 2.7 0.3 size() v: 3 v[0] v[1] v[2] 2.7 5.6 0.3 size() v: 3 v[0] v[1] v[2] 5.6 0.3 0.3 size() v: 2 v[0] v[1] 5.6 0.3 Wie löscht man die anderen Elemente? z.B. indem man alle hinter dem Löschelement gespeicherten Elemente um einen Platz nach vorne kopiert und danach das letzte Element mit pop_back() löscht (siehe rechts) 24.03.2011 C++ Grundlagen 72 Gültigkeits- und Sichtbarkeitsbereich von Variablen FB Informatik Prof. Dr. R.Nitsch Bisher: Variablen sind gekennzeichnet durch Name (name), Typ (type), Wert (value) und Adresse. Neu: Zusätzlich sind Variable charakterisiert durch ihren Gültigkeitsbereich ihren Sichtbarkeitsbereich (Visibility) Gültigkeitsbereich (GB) einer Variablen ist der Programmtextblock, in dem für die Variable ein Speicherplatz reserviert ist. Der Sichtbarkeitsbereich (SB) einer Variablen ist der Programmtextblock, in dem eine Variable über ihren Namen gelesen oder geändert werden kann. 24.03.2011 C++ Grundlagen 73 Gültigkeits- und Sichtbarkeitsbereich von Namen Beispiel #include <iostream> using namespace std; int a=3, b=10; int gib_a() { return a;} int gib_c() { return c; } int main () { cout << a << endl; auto int a = 10; cout << a << endl; cout << ::a << endl; FB Informatik Prof. Dr. R.Nitsch // externe (globale) Variable (R1: SB=Datei, GB=Programm) // Fehler: c nicht definiert // hier beginnt ein Anweisungsblock // Ausgabe 3; globales a (R3) auto gibt explizit die Speicherklasse "Automatisch" an! // lokales a; auto ist voreingestellt und deshalb optional // Ausgabe 10; lokales a (R4) // Ausgabe 3; globales a // Gültigkeitsbereich-Auswahloperator { // Subblock beginnt (R3) auto int b = 20; // lokales b sichtbar; globales b gültig, aber unsichtbar (R4) // lokales c; hier ist auto wie üblich wieder weggelassen int c = 30; cout << b << c << ::b << endl; // Ausgabe 20 30 10 } // hier endet Gültigkeitsbereich von lok. b und c // Ausgabe 10; globales b wieder sichtbar cout << b << endl; cout << c << endl; // Fehler: c nicht mehr gültig (R2) cout << a << endl; // Ausgabe 10; lokales a wieder sichtbar (R4) // Ausgabe 3; globales a cout << ::a << endl; // lokales a wird unsichtbar und ungültig return 0; } 24.03.2011 C++ Grundlagen 74 Lokale contra globale Variablen FB Informatik Prof. Dr. R.Nitsch Das spricht für globale Variablen Sie werden vom Compiler initialisiert (mit 0) Ihr Gültigkeitsbereich ist das ganze Programm Ihr Sichtbarkeitsbereich ist die Datei, in der sie definiert sind Sie können in allen Funktionen benutzt werden Sie können auch bei Verdeckung mit Operator :: sichtbar gemacht werden Das spricht gegen globale Variable Sie genießen keinen Zugriffsschutz. Jeder kann überall im Programm auf sie zugreifen. Hat eine globale Variable einen unerwarteten Wert, muss die Ursache im gesamten Programm gesucht werden. Sie machen Programme unzuverlässig. Gute Programmierer wissen (nach vielen Fehltritten) Schutz der Daten vor unberechtigtem Zugriff ( -> Kapselungsprinzip ) verbessert die Datenintegrität macht Programme zuverlässiger, vereinfacht die Fehlersuche macht Programme besser wartbar und pflegbar. 24.03.2011 C++ Grundlagen Deshalb: Deshalb: Globale Globale Variable Variable sollten sollten nur nur für für read-only read-only (const) (const) Variable Variable verwendet verwendet werden. werden. 75 namespace std /61/ FB Informatik Prof. Dr. R.Nitsch C++ ermöglicht die Schaffung eigener Sichtbarkeitsbereiche mit Namen (sogenannte Namensräume oder namespaces) Namensbereiche spielen bei der Benutzung verschiedener Libraries eine Rolle So sind alle Bestandteile der C++-Standardbibliothek im Namensraum std definiert. Will man Elemente eines Namensraumes benutzen, muss man "qualifizierte Namen" (solche mit vorangestelltem Bezeichner des Namensraums) verwenden, um das Element sichtbar zu machen. std::cout << name << ", " << age << std::endl; float y = std::sin(x); Alternativ kann man dem Compiler mit using-Deklarationen mitteilen "Mit cout meine ich immer std::cout und mit sin immer std::sin" using std::cout; using std::endl; using std::sin; cout << name << ", " << age << endl; float y = sin(x); Ausprobieren mit cppbuch/k2/bloecke.cpp Eine noch weitergehende Alternative ist eine using directive. Sie sagt dem Compiler: "Findest Du einen Namen nicht im aktuellen Sichtbarkeitsbereich, dann suche ihn im Namensraum std" using namespace std; cout << name << ", " << age << endl; float y = sin(x); 24.03.2011 C++ Grundlagen 76 Software-Qualitätskriterien FB Informatik Prof. Dr. R.Nitsch Zuverlässigkeit:= Korrektheit + Robustheit Korrektheit: Aufgaben exakt so erfüllen, wie sie durch Anforderungskatalog bzw. Spezifikationen definiert sind. Robustheit: Fähigkeit von Softwaresystemen, auch unter außergewöhnlichen Bedingungen zu funktionieren, die nicht in der Spezifikation ausdrücklich beschrieben sind. Pflegbarkeit:= Erweiterbarkeit + Wartbarkeit Geringer Aufwand zur Durchführung von Änderungen aufgrund von neuen Anforderungen (Erweiterbarkeit) oder im Fehlerfall (Wartbarkeit) Wiederverwendbarkeit Eigenschaft von Softwareprodukten, ganz oder teilweise für neue Anwendungen wiederverwendet werden zu können Benutzerfreundlichkeit (Usability) Einfach bei Bedienung, Bereitstellen von Eingabedaten, Auswertung der Ergebnisse und Wiederaufsetzen nach Benutzungsfehlern Effizienz bzw. Performanz: Geringer Speicherplatzverbrauch, akzeptables Zeitverhalten 24.03.2011 C++ Grundlagen 77 Fundamentale Software-Entwurfsprinzipien FB Informatik Prof. Dr. R.Nitsch Dekomposition Zerlegen der Gesamtaufgabe in möglichst unabhängige Teilaufgaben (Teile&Hersche) Ziel: Große Kohäsion, kleine Kopplung Große Kohäsion Jeder Programmbaustein, wie. z.B. Funktion, Klasse , Modul, konzentriert sich auf die Erledigung genau einer Teilaufgabe Geringe Kopplung Die Programmbausteine benutzen möglichst wenige andere Programmbausteine zur Aufgabenerfüllung, d.h. geringe Abhängigkeiten zwischen den Programmbausteinen Trennung von Schnittstelle und Implementierung Die Implementierung des Programmbausteins Modularisierung umfasst den Code für die Funktionalität Ziel: Programmstrukturierung Die Schnittstelle von Programmbausteinen definiert ihre Funktionalität und dient dem Gesamtsystem wird in sinnvolle Module Anwender als Benutzungsanleitung. zerlegt. Das Modul dient dabei als Behälter für Funktionen oder Zuständigkeiten des Zweck: Komplexität vor Anwender verbergen Systems. Wer Wermitreden mitredenwill, will,muss mussdiese dieseBegriffe Begriffekennen! kennen! Abstraktion Weglassen von irrelevanten Details, und Konzentration auf das Wesentliche Ziel: Verbergen von Komplexität Kapselung (information hiding) Zusammengehörige Bestandteile einer Abstraktion werden zu einem Ganzen zusammengefasst und von anderen abgegrenzt. 24.03.2011 C++ Grundlagen 78 Funktionsabstraktion FB Informatik Prof. Dr. R.Nitsch Funktionen in Programmiersprachen sind eine Abstraktion in folgendem Sinn wiederkehrende Progammstücke werden zusammengefasst und benannt Ihr Name abstrahiert von dem Programmstück, ihrem Rumpf Jedes Auftreten des Programmstücks wird durch einen Aufruf der Abstraktion ersetzt. Veränderliche Teile des Abstraktionsrumpfes werden zu formalen Parametern gemacht. Beim Aufruf werden aktuelle Parameter für die formalen eingesetzt Einsetzen des Rumpfes mit Substitution der Parameter Abstraktionen erlauben das Verbergen von Implementierungsdetails Benutzersicht Was tut eine Abstraktion? Vor- und Nachbedingung, “Effekt” Implementierersicht Wie ist sie realisiert? Algorithmus, Effizienz, . . . Abstraktion (lat. abstractus – „abgezogen“, Partizip Perfekt Passiv von abs-trahere – „abziehen, entfernen, trennen“) bezeichnet meist den induktiven Denkprozess des Weglassens von Einzelheiten und des Überführens auf etwas Allgemeineres oder Einfacheres [Wikipedia] 24.03.2011 C++ Grundlagen 79 Abstraktionen in Programmiersprachen FB Informatik Prof. Dr. R.Nitsch Weitere Abstraktionen in Programmiersprachen sind Funktionsabstraktion Prozedurabstraktion generische Abstraktion Eine Prozedurabstraktion abstrahiert von einem Befehl Jeder Aufruf wird ausgeführt und verändert den Speicherzustand Der "kleine" Unterschied Prozeduren abstrahieren von Befehlen (z.B. "sortiere", "gib aus", "lies ein", "speichere", ...) Funktionen abstrahieren von Ausdrücken. Jeder Aufruf liefert einen Wert. C++ unterstützt mit Funktionen, die nichts zurückgeben (Rückgabetyp void) die Prozedurabstraktion. 24.03.2011 C++ Grundlagen 80 Wozu Prozeduren/Funktionen? FB Informatik Prof. Dr. R.Nitsch Welche Entwurfsprinzipien werden von Funktionen/Prozeduren unterstützt? Abstraktion? Kapselung Mudularisierung? Dekompisition? Kohäsion? Kopplung? Trennung von Schnittstelle und Implementierung? Funktionsabstraktion Input Output ? Schnittstelle Implementation Prozedurabstraktion Input ? Schnittstelle Implementation Prozedur/Funktion als Black-Box-Abstraktion 24.03.2011 C++ Grundlagen 81