Einführung C++ im Textfenster



Ähnliche Dokumente
Einführung in die Programmierung

Funktionen Häufig müssen bestimmte Operationen in einem Programm mehrmals ausgeführt werden. Schlechte Lösung: Gute Lösung:

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2015/2016 Wirtschaftsingenieur Bachelor 5. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

Einführung in die C++ Programmierung für Ingenieure

Unterprogramme. Funktionen. Bedeutung von Funktionen in C++ Definition einer Funktion. Definition einer Prozedur

Angewandte Mathematik und Programmierung

Grundlagen der Programmiersprache C++

1 Vom Problem zum Programm

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 16

Hochschule Darmstadt Informatik-Praktikum (INF 1) WS 2014/2015 Wirtschaftsingenieur Bachelor 4. Aufgabe Datenstruktur, Dateieingabe und -ausgabe

5 DATEN Variablen. Variablen können beliebige Werte zugewiesen und im Gegensatz zu

Übungen zu C++ Kapitel 1

Wintersemester Maschinenbau und Kunststofftechnik. Informatik. Tobias Wolf Seite 1 von 18

Modellierung und Programmierung 1

Klausur in Programmieren

Programmierung in C. Grundlagen. Stefan Kallerhoff

Einführung in die Programmierung (EPR)

Zählen von Objekten einer bestimmten Klasse

Erwin Grüner

Einführung in die Programmierung

Die elementare Ausgabe von Daten auf externe Medien, wie Dateien und das Einlesen davon wird demonstriert.

Der Aufruf von DM_in_Euro 1.40 sollte die Ausgabe 1.40 DM = Euro ergeben.

Programmieren in C. Felder, Schleifen und Fließkommaarithmetik. Prof. Dr. Nikolaus Wulff

Informatik Repetitorium SS Volker Jaedicke

Erweiterung der Aufgabe. Die Notenberechnung soll nicht nur für einen Schüler, sondern für bis zu 35 Schüler gehen:

Grundlagen. Kapitel 1

Die Programmiersprache C99: Zusammenfassung

Praktikum Ingenieurinformatik. Termin 2. Verzweigungen (if-else), printf und scanf, while-schleife

Einführung in die C-Programmierung

Deklarationen in C. Prof. Dr. Margarita Esponda

Programmierkurs Java

2. Semester, 2. Prüfung, Lösung

Die Programmiersprache C

2. Programmierung in C

Kontrollstrukturen und Funktionen in C

3 Die Grundrechenarten

Java 7. Elmar Fuchs Grundlagen Programmierung. 1. Ausgabe, Dezember 2011 JAV7

Hochschule München, FK 03 FA SS Ingenieurinformatik

Fallunterscheidung: if-statement

Excel Funktionen durch eigene Funktionen erweitern.

C++ Grundlagen. ++ bedeutet Erweiterung zum Ansi C Standard. Hier wird eine Funktion eingeleitet

Einführung in die Java- Programmierung

Binäre Bäume. 1. Allgemeines. 2. Funktionsweise. 2.1 Eintragen

FB Informatik. Fehler. Testplan

Inhaltsverzeichnis. Grundbegriffe der C-Programmierung Für den HI-TECH C-Compiler

Zum Abschluss wird gezeigt, wie aus einem C++ Quell-Programm ein ausführbares Programm erzeugt wird. 1. Installation von NetBeans...

Programmieren in C. Macros, Funktionen und modulare Programmstruktur. Prof. Dr. Nikolaus Wulff

Klausur in Programmieren

Modul 122 VBA Scribt.docx

Aufgaben zur C-Programmierung für die Praktikumsperiode des 1.Semesters

M. Graefenhan Übungen zu C. Blatt 3. Musterlösung

Vorkurs C++ Programmierung

Übungen zu Einführung in die Informatik: Programmierung und Software-Entwicklung: Lösungsvorschlag

Pass by Value Pass by Reference Defaults, Overloading, variable Parameteranzahl

Objektorientierte Programmierung

Eine Einführung in C-Funktionen

Übungskomplex Felder (1) Eindimensionale Felder Mehrdimensionale Felder

Mediator 9 - Lernprogramm

Kontrollstrukturen, Strukturierte Programmierung

Arbeiten mit UMLed und Delphi

Projektverwaltung Problem Lösung: Modulare Programmierung

Dokumentation IBIS Monitor

Diana Lange. Generative Gestaltung Operatoren

Lineargleichungssysteme: Additions-/ Subtraktionsverfahren

Delegatesund Ereignisse

Schmitt, Günter (1996): Fortran 90 Kurs technisch orientiert, R. Oldenbourg Verlag, München

Kurze Einführung in die Programmiersprache C++ und in Root

1Schnelleinstieg 14. 2Wie aus einer einfachen Textdatei. 3 Wie man eigene Programme erstellt 30. Inhaltsverzeichnis. ein Programm wird 20

S7-Hantierungsbausteine für R355, R6000 und R2700

Informationen zur Verwendung von Visual Studio und cmake

Zusammenfassung des Handzettels für Programmieren in C

Dateiname Name(n) und Matrikelnr. des/der Bearbeiter Tel.-Nr. und -Adresse für den Fall, dass die Diskette nicht lesbar ist.

Informatik. Studiengang Chemische Technologie. Michael Roth WS 2012/2013. Hochschule Darmstadt -Fachbereich Informatik-

Sin-Funktion vgl. Cos-Funktion

Zusammengesetzte Datentypen -- Arrays und Strukturen

Starten Sie Eclipse: Hier tragen sie Ihr Arbeitsverzeichnis ein. Zu Hause z.b. c:\workspace.

Übersicht Programmablaufsteuerung

Das Typsystem von Scala. L. Piepmeyer: Funktionale Programmierung - Das Typsystem von Scala

Datentypen. Agenda für heute, 4. März, Pascal ist eine streng typisierte Programmiersprache

Einführung in die Programmierung

1 Mathematische Grundlagen

Studentische Lösung zum Übungsblatt Nr. 7

Wir arbeiten mit Zufallszahlen

affilinet_ Flash-Spezifikationen

Datenbanken Kapitel 2

Felder, Rückblick Mehrdimensionale Felder. Programmieren in C

Stellen Sie bitte den Cursor in die Spalte B2 und rufen die Funktion Sverweis auf. Es öffnet sich folgendes Dialogfenster

Einführung Datentypen Verzweigung Schleifen Funktionen Dynamische Datenstrukturen. Java Crashkurs. Kim-Manuel Klein

Ingenieurinformatik Diplom-FA (C-Programmierung)

5. Tutorium zu Programmieren

Anleitung über den Umgang mit Schildern

Wiederholung, Abbruch von Schleifen, switch-anweisung Datentypen, char, formatierte Ausgabe

Outlook. sysplus.ch outlook - mail-grundlagen Seite 1/8. Mail-Grundlagen. Posteingang

Einführung zum Arbeiten mit Microsoft Visual C Express Edition

Programmieren I. Kontrollstrukturen. Heusch 8 Ratz Institut für Angewandte Informatik

Text Formatierung in Excel

Programmentwicklung mit C++ (unter Unix/Linux)

Grundlagen der Programmierung Prof. H. Mössenböck. 3. Verzweigungen

Tutorium Rechnerorganisation

Programmiersprachen Einführung in C. Unser erstes C-Programm. Unser erstes C-Programm. Unser erstes C-Programm. Unser erstes C-Programm

Transkript:

Einführung C++ im Textfenster Rudolf Lehn Schülerforschungszentrum Bad Saulgau 5. Januar 2007

Inhaltsverzeichnis 1 Einführung 1 1.1 Erste Schritte mit C++ 1 1.1.1 Typische C++ Umgebung 1 1.1.2 Das erste C++ Programm 2 1.1.3 Addition zweier ganzer Zahlen 4 1.1.4 Binäre arithmetische Operatoren 5 1.1.5 Zusammenfassung zu Kapitel 1 6 2 Kontrollstrukturen 7 2.1 Verzweigungen 7 2.2 Schleifen 8 2.2.1 while-schleife 8 2.2.2 Zuweisungsoperatoren 9 2.2.3 for Schleife 11 2.2.4 do-while Schleife 11 2.2.5 Zusammenfassung zu Kapitel 2 14 3 Funktionen 16 3.1 Mathematische Bibliotheksfunktionen 16 3.2 Definition von Funktionen 17 3.3 Funktionsprototypen 18 3.4 Header-Dateien 18 3.5 Zufallszahlengenerator 20 3.5.1 Zufallszahlengenerator im Textfenster 20 3.6 Übergabeparameter bei Funktionen 21 3.6.1 Übergabe per Wert - call-by-value 21 3.6.2 Übergabe per Referenz - call-by-reference 21 3.7 Überladen von Funktionen 22 3.8 Funktionstemplates 23 3.9 Zusammenfassung zu Kapitel 3 24 4 Arrays 27

Inhaltsverzeichnis 4.1 Deklaration von Arrays 27 4.2 Beispiele mit Arrays 27 4.2.1 Initialisieren eines Arrays 27 4.2.2 Verteilung der Augenzahl beim Würfeln 29 4.3 Übergabe von Arrays an Funktionen 30 4.4 Mehrdimensionale Felder 32 4.5 Zusammenfassung zu Kapitel 4 33 5 Dateiverarbeitung 34 5.1 Dateioperationen 34 5.1.1 File-Stream-Klassen 34 5.1.2 Anwendung in der Physik 38 5.2 Grundlagen zu Gnuplot 41 5.3 Zusammenfassung zu Kapitel 5 45 6 Pointer und String 46 6.1 Deklaration und Initialisierung von Pointer 46 6.2 Pointeroperatoren 49 6.3 Parameterübergabe mit Zeigern bei Funktionen 49 6.4 Pointerausdrücke und Pointerarithmetik 50 6.4.1 Arrays von Pointer 51 6.5 Zeichen- und String-Verarbeitung 52 6.5.1 Grundlagen 52 6.6 Stringmanipulationen 53 6.7 C++ Standardtyp vector 54 6.8 C++ Standardtyp string 56 6.9 Zusammenfassung zu Kapitel 6 58 7 Klassen und Datenabstraktion 59 7.1 Strukturierte Datentypen 59 7.2 Klassen und Objekte 60 7.3 Initialisierung und Konstruktoren 63 7.3.1 Standardkonstruktor 63 7.3.2 Allgemeine Konstruktoren 65 7.4 Der this-zeiger 66 7.5 Klassentemplates 67 7.6 Überladen von Operatoren 67 7.7 Zusammenfassung zu Kapitel 7 67 8 Simulationen in der Physik 69 9 GNU-Debugger DDD - für Linux 70 9.1 Bedienung des DDD 71

Das folgende Skript gibt eine grundlegende Einführung in die C++ Programmierung. Literatur: Deitel & Deitel: C++ How to program Ulrich Breymann: C++ - Einführung und professionelle Programmierung P. Prinz et. al.: C++ Lernen und professionell anwenden S. Luding et. al.: Physik auf dem Computer I & II, Vorlesungsmanuskript Uni- Stuttgart (http://www.ica1.uni-stuttgart.de/~lui/script/computerphysik.html) Dietmar Herrmann: C++ für Naturwissenschaftler Ein Update des Skripts wird auf der URL www.sfz-bw.de veröffentlicht. Hinweise und Korrekturen werden erbeten an sfz@rlehn.com.

1. Einführung 1.1. Erste Schritte mit C++ 1.1.1. Typische C++ Umgebung Ein C++ System hat im Allgemeinen einen Editor zur Entwicklung des Programms, die C++ Programmiersprache und die C++ Standardbibliothek. C++ Programme durchlaufen typischerweise sechs Phasen: 1. editieren (edit), 2. compilieren (compile) und linken (link), 3. Ablauf des Programms (execute). C++ Programme werden mit der Extension.cc,.cpp,.C,.cxx oder.c++ geschrieben. Auf UNIX/LINUX-Systemen werden im einfachsten Fall zum Editieren vi oder emacs verwendet. Auf einem MAC kann z. B. SubEthEdit oder TextMatein ähnlicher Weise verwendet werden. KED bei Linux oder OS X bei MAC oder Borland bzw. Microsoft bei Windows haben ihre Editoren integriert. Der Compiler übersetzt das C++ Programm in den Maschinencode (Objekt Code: programm.o). Im anschließenden Linkvorgang werden die verschiedenen Teilprogramme (teilprogramm_i.o, i = 1... n) zu einem ausführbaren Programm zusammengebunden (gelinkt). Auf einem typischen UNIX-basierten System lautet der Befehl für das Compilieren und anschließende Linken eines C++ Programms: g++ steht für GNU (GNU is not Unix). c++ programm.cc oderg++ programm.cc 1

1. Einführung 2 Nach einer fehlerfreien Übersetzung wird eine Datei a.out erzeugt, welche das ausführbare Programm von programm.cc ist. Bei IDE Systemen (Integrated Development Environment), bei denen der Editor integriert ist, wird meist gleich aus dem programm.cc eine ausführbare Datei erzeugt, die wieder programm heißt (Unter Windows als programm.exe). Mit verschiedenen Optionen (vgl. unter Unix/Linux die Hilfeman g++) lassen sich neben vielen anderen Dingen auch Verzeichnisse für Include-Dateien oder auch die Objektdateinamen sowie des lauffähigen Programms festlegen. g++ -IVerzeichnisHeader -o LauffaehigesProgramm programm.cc Hilfreich bei der Fehlersuche kann auch die Ausgabe aller Warnungen mit-wall sein g++ -Wall -IVerzeichnisHeader -o LauffaehigesProgramm programm.cc 1.1.2. Das erste C++ Programm 1 // hello. cc 2 #include <iostream> 3 int main () 4 { 5 std :: cout << "Hello SFZ Friends!\n"; 6 return 0; // Programm erfolgreich beendet 7 } Hinweise: Ab // in einer Zeile steht ein Kommentar. Jedes Programm sollte mit einem Kommentar beginnen, der den Zweck des Programms beschreibt. Mehrzeilige Kommentare werden in /*... */ eingeschlossen. Jede Anweisung wird mit einem Strichpunkt abgeschlossen. C++ unterscheidet Groß- und Kleinschreibung. #include <iostream> ist eine Präprozessoranweisung, d. h. der Präprozessor soll das input/output stream header file <iostream> in das Programm einfügen. int main() ist Teil eines jeden C++ Programms. Das Schlüsselwort int zeigt an, dass main eine ganze Zahl zurückgibt. Die Klammern { und } schließen den Funktionskörper von Funktionen, wie auch der Funktion main ein. Ausgaben und Eingaben werden in C++ mit sogenannten Strömen (stream) von Zeichen dargestellt. Das sind

1. Einführung 3 Objekte, die eine Folge von Bytes aufnehmen und ausgeben können. In der 5. Zeile wird ein Strom von Zeichen Hello SFZ-Friends! an das Standardausgabestromobjekt std::cout gesandt. Mit << wird der rechtsstehende Operand in den Ausgabestrom (output stream) eingefügt. Das Zeichen\n wird nicht auf dem Bildschirm ausgegeben, sondern ist eine sogenannte escape Sequenz, die den Cursor an den Anfang der nächsten Zeile setzt. std:: gibt an, dass ein Objekt (z. B.cout) zum Namensbereichstd gehört. return 0; gibt am Ende der main Funktion an, dass das Programm erfolgreich beendet wurde. Diese Anweisung kann fehlen. Dann wird automatisch 0 zurückgegeben. Das Consolenfenster erscheint unter Windows nur kurze Zeit. Dies kann mit der Anweisung system("pause"); verhindert werden: Im Folgenden wird die Hauptfunktion main generell mit zwei Parametern aufgerufen. Dies ist notwendig, wenn beim Programmaufruf dem Programm Parameter übergeben werden sollen. Bei der grafischen Oberfläche Qt ist dies z. B. erforderlich. 1 // helloparameter. cc 2 #include <iostream> 3 4 int main (int argc, char * argv[]) 5 { 6 std :: cout << "argc = " << argc << "\n\n"; 7 std :: cout << "argv[0] = " << argv[0] << std::endl; 8 std :: cout << "Hallo " << argv[1] << "!\n"; 9 return 0; // Programm erfolgreich beendet 10 } Hinweis: Dieses Programm sollte auf einfache Weise mit einem Editor geschrieben und dann mit C++ übersetzt werden, damit die Programmparameter angegeben und ausgelesen werden können. Möglicher Programmaufruf:./a.out SFZ-Freunde. Der erste Parameter argc braucht nicht übergeben zu werden. Er wird vom Compiler als Zähler für die in argv eingegebenen, durch Leerzeichen getrennte Texte verwendet. Statt *argv[] kann auch **argv verwendet werden. Dies sind sogenannte Pointerschreibweisen (vgl. Kap 6 ). Der Name des erzeugten Programms (z. B. meistens einfach./a.out) ist automatisch in argv[0] gespeichert. In den folgenden Feldelementen sind die weiteren Parameter abgelegt. Hinweis Die Programmbeispiele sind auf der SFZ-WEB-Seite abgelegt. Die Seite ist über die SFZ-Seite Materialien zur Informatik erreichbar.

1. Einführung 4 1.1.3. Addition zweier ganzer Zahlen 1 // Addition zweier ganzer Zahlen 2 #include <iostream> 3 using namespace std; // Namensraum std der Standardbibliothek benutzen 4 int main(int argc, char * argv[]) 5 { 6 int integer1, integer2, sum; // Deklaration 7 cout << "Gib die erste ganze Zahl ein:\n"; // Prompt der Eingabe 8 cin >> integer1 ; // Eingabe 9 cout << "Gib die zweite ganze Zahl ein:\n"; // Prompt der Eingabe 10 cin >> integer2 ; // Eingabe 11 sum = integer1 + integer2 ; // Berechnung der Summe 12 cout << "Die Summe ist " << sum << endl; // Ausgabe 13 return 0; // Programm erfolgreich abgeschlossen 14 } Bemerkungen: using namespace std; macht alle Befehle aus der Standardbibliothek bekannt (z. B. cout, cin, endl). Dadurch kann im Programm das Präfix std:: weggelassen werden, d. h. z. B.cout stattstd::cout. Zeile 6) integer1, integer2, sum sind Namen für Variable vom Typ int, d. h. ganze Zahlen. Ein Variablenname besteht aus Buchstaben, Ziffern und einem _. Der Variablenname darf nicht mit einer Ziffer beginnen. Vermeide Variablennamen, welche mit einem _ beginnen, da C++ Compiler häufig solche Variablennamen selbst verwenden. Zeile 8) In cin >> integer1 übergibt cin einen Wert an integer1. Zeile 11) sum = integer1 + integer2; weist der Speichervariablen sum die Summe von integer1 und integer2 zu. Merke: sum muss auf der linken Seite des Zuweisungsoperators = stehen! cout << "Die Summe ist "<< sum << endl; gibt den Text Die Summe ist und den Wert der Variablen sum aus mit abschließendem endl. Dadurch wird die Zeile mit einem Zeilenvorschub abgeschlossen. Weitere wichtige elementare Datentypen sind double für Gleitkommazahlen und char für Zeichen.

1. Einführung 5 1.1.4. Binäre arithmetische Operatoren Binäre arithmetische Operatoren werden auf zwei Operanden angewandt. Der Ausdruck integer1 + integer2 enthält den binären Operator + und die beiden Operanden integer1 und integer2. Operation Arithmetischer Algebraische C++ Operation Operator Schreibweise Schreibweise Addition + x + 7 x+7 Subtraktion u w u-w Multiplikation ac a*c r Division / r/t t Modulodivision % x mod 11 x % 11 Hinweis: Sind bei einer Division sowohl Zähler als auch Nenner ganzzahlig, dann ist auch das Ergebnis in C++ ganzzahlig.7/4 ergibt 1. Der Rest entfällt! % gibt den Rest bei der Division zweier ganzer Zahlen. Klammern werden in C++ Ausdrücken in der gleichen Weise wie in algebraischen Ausdrücken verwendet. Allerdings gibt es nur runde Klammern. Außerdem gelten die üblichen Rechenregeln Punkt vor Strich.

1. Einführung 6 1.1.5. Zusammenfassung zu Kapitel 1 1. Wichtigste Elemente eines C++-Programms // hello.cpp #include <iostream> int main(int argc, char * argv[]) { std :: cout << "Hello SFZ Friends!\n"; return 0; // Programm erfolgreich beendet } Vor jedes Objekt gehört die Klasse, aus welcher das Objekt abgeleitet ist. Die std Klasse wird mit std:: oder mit using std::objekt bzw. allgemein mit using namespace std; angegeben. Objekte aus std sind z. B.cout,cin,endl. 2. Escape Sequenzen Einzelzeichen Bedeutung ASCII-Wert (dezimal) \a alert (BEL) 7 \n line feed (LF) 10 \t horizontal tab (HT) 9 \r carriage return (CR) 13 \\ \ 92 \" " 34 3. cout (console output) cout << "Hello SFZ-Friends!" << endl; odercout << "Hello SFZ-Friends!\n"; gibt den Text Hello SFZ-Friends! auf dem Bildschirm aus. endl oder \n erzeugen einen Zeilenvorschub. 4. cin (console input) cin >> x ; // liest von der Tastatur in die Variable x 5. Arithmetische Operatoren+,-,*,/,% 6. Datentypen char - Zeichen int - ganze Zahlen double - Gleitpunktzahlen

2. Kontrollstrukturen Es kommt sehr häufig vor, dass die Anweisungen in einem Programm nicht alle hintereinander ausgeführt werden können. Verzweigungen und Schleifen steuern den Programmverlauf. 2.1. Verzweigungen Mit der Verzweigungsanweisung if-else kann eine Auswahl zwischen zwei verschiedenen Anweisungen getroffen werden. Vergleichsoperatoren Algebraische C++ Beispiel Schreibweise Schreibweise > > x > y < < x < y >= x >= y <= x <= y = == x == y =!= x!= y Beispiel in Alltagssprache C++ Anweisungen Wenn PunktProz>=40 if ( PunktProz>=40) Ausgabe: "Pruefung bestanden!" cout<<"pruefung bestanden!\n"; Sonst else Ausgabe: "Pruefung wiederholen!"; cout<<"pruefung wiederholen!\n"; Bei der Programmausführung wird zunächst die Bedingung PunktProz>=40 bewertet. Ist das Ergebnis true, so wird Pruefung bestanden, andernfalls Pruefung wiederholen ausgegeben. Gibt es keinenelse-zweig und liefert dieif-bedingung den Wertfalse, dann wird direkt zur nächsten Anweisung nach derif-anweisung verzweigt. 7

2. Kontrollstrukturen 8 Ein logischer Ausdruck kann in C++ ein ganz allgemeiner arithmetischer Ausdruck sein. Wenn sein Wert 0 ist, dann wird er als false behandelt. C++ stellt auch einen Datentypbool zur Verfügung. Er kann die Wertetrue undfalse annehmen, wobei intern fürtrue der Wert 1 gesetzt wird. In C++ gibt es einen Auswahloperator?:, der wie eine if-else Verzweigung angesehen werden kann. Es ist der einzige C++ Operator mit drei Operanden: Der erste Operand ist eine Bedingung, der zweite Operand liefert das Ergebnis, wenn diese Bedingung true ist und der dritte Operand liefert das Ergebnis, wenn diese Bedingung false ist. cout << (PunktProz >= 40? "Pruefung bestanden": "Pruefung wiederholen"); Hier wird Pruefung bestanden ausgegeben, wenn PunktProz>=40 true ist, andernfalls wird Pruefung wiederholen ausgegeben. Hinweis: Wenn zu einerif oderelse Verzweigung mehrere Anweisungen gehören, dann müssen diese in{...} eingeschlossen werden. 2.2. Schleifen Schleifen werden gebildet, um Anweisungen öfters auszuführen. C++ bietet drei Sprachelemente zur Bildung von Schleifen: while, for und do-while. Die Anzahl der Schleifendurchläufe wird jeweils durch eine Laufbedingung festgelegt. 2.2.1. while-schleife Beispiel Bei einem Physikexperiment werden Messwerte aufgenommen. Bestimme den Mittelwert. C++ Programm 1 // Mittelwertberechnung aus beliebig vielen Messwerten 2 #include <iostream> 3 using namespace std; 4 5 int main(int argc, char * argv[]) 6 { 7 double

2. Kontrollstrukturen 9 8 messwert, // Messwert 9 mittelwert; // Mittelwert der eingegebenen Messwerte 10 // Initialisierung 11 double gesamt = 0; // Summe der Messwerte, Loesche Summenspeicher 12 int anzahl = 0; // Anzahl der Messwerte 13 14 // Ablaufphase 15 cout<<"messwert, ( 1 Ende): "; 16 cin>> messwert; 17 18 while ( messwert >= 0 ) { 19 gesamt = gesamt + messwert; 20 anzahl = anzahl + 1; 21 cout<<"messwert, ( 1 Ende): "; 22 cin>>messwert; 23 } 24 25 // Abschlussphase 26 if ( anzahl!= 0) { 27 mittelwert = gesamt/anzahl; 28 cout << "Mittelwert = " << mittelwert << endl; 29 } 30 else 31 cout << "Es wurden keine Messwerte eingegeben!" << endl; 32 33 return 0; // Programm erfolgreich beendet 34 } Hinweise 1. Die Variablen gesamt und anzahl wurden initialisiert. Eine Variable, welche nicht initialisiert wurde, enthält einen Wert, der zufällig zuvor in dem der Variable zugeordneten Speicherplatz abgelegt wurde. 2. while (messwert>=0) gibt an, dass die while Struktur soll so lange durchlaufen wird, wiemesswert >=0 ist. 3. Die Messwerte, die Summe der Messerte und der Mittelwert werden als Dezimalzahl abgespeichert. Hierzu sind in C++ die Datentypendouble zu verwenden. 2.2.2. Zuweisungsoperatoren Eine einfache Zuweisung ordnet einer Variablen mit Hilfe des Zuweisungsoperators = den Wert eines Ausdrucks zu. Hierbei steht die Variable immer links und der zugewie-

2. Kontrollstrukturen 10 sene Wert immer rechts vom Zuweisungsoperator. Beispiel z = 7.5; x = 2.6 + 4.3 * z; Neben dem einfachen Zuweisungsoperator gibt es die zusammengesetzten Zuweisungsoperatoren. Beispiel a = a + 3; kann ersetzt werden durch a += 3; (!kein Leerzeichen zwischen+und=!) Der += Operator addiert den Wert des Ausdrucks auf der rechten Seite des Operators zum Wert der Variablen auf der linken Seite und speichert das Ergebnis in der Variablen auf der linken Seite des Operators. Mit jedem binären arithmetischen Operator (+,-,*,/,%), kann ein zusammengesetzter Zuweisungsoperator gebildet werden. Es gibt also+=,-=,*=,/=,%=. In C++ verwendet man oft zum Inkrementieren bzw. Dekrementieren einer Variablen die unären Operatoren++ bzw.--. So sind die Anweisungen a = a+1;, a += 1; und a++; gleichwertig. Allerdings kann ein Inkrement- bzw. Dekrementoperator hinter oder vor einer Variablen stehen. Überprüfe die Wirksamkeit von++ bzw.-- mit folgendem C++ Programm: 1 // Praeinkrement und Postinkrement 2 #include <iostream> 3 using namespace std; 4 5 int main(int argc, char * argv[]) 6 { 7 int c; 8 9 c = 5; 10 cout << c << endl; // Ausgabe 5 11 cout << c++ << endl; // Ausgabe 5 dann inkrementieren ( Postinkrement) 12 cout << c << endl << endl; // Ausgabe 6 13 14 c = 5; 15 cout << c << endl; // Ausgabe 5 16 cout << ++c << endl; // Praeinkrement dann Ausgabe 6 17 cout << c << endl; // Ausgabe 6 18 19 return 0; // Programm erfolgreich beendet 20 }

2. Kontrollstrukturen 11 2.2.3. for Schleife Diefor Schleife ist eine typische zählergesteuerte Schleife. 1 // Praeinkrement und Postinkrement in der for Schleife 2 #include <iostream> 3 using namespace std; 4 5 int main(int argc, char * argv[]) 6 { 7 // Initialisierung, Wiederholungsbedingung und Inkrementierung 8 // sind alle in der for Schleife enthalten 9 10 for ( int zaehler=1; zaehler <= 10; zaehler++) 11 cout << zaehler << endl; 12 13 return 0; // Programm erfolgreich beendet 14 } ++ kann vor oder hinter der Zählervariablen stehen. Das allgemeinefor-format ist for ( Initialisierung; Schleifenwiederholungstest; Inkrementierung) Anweisung Hinweis Wenn die Kontrollvariable in der for-schleife definiert wird, dann kann diese Variable nur in dieserfor-schleife benutzt werden. Die drei Ausdrücke in der for-schleife sind optional! Wenn z. B. der Schleifenwiederholungstest fehlt, dann nimmt C++ an, dass die Schleife unendlich oft durchlaufen werden soll. Man kann die Initialisierung der Laufvariablen weglassen, sofern diese Variable sonst wo im Programm initialisiert worden ist. Ebenso kann auch die Inkrementierung sonst irgendwo im Schleifenkörper durchgeführt werden. 2.2.4. do-while Schleife Die do-while-schleife ist ganz ähnlich zur while-schleife. Während jedoch bei der while-schleife die Schleifendurchlaufbedingung am Anfang der Schleife getestet wird, testet die do-while-schleife erst am Ende der Schleife, ob nochmals ein Durchgang

2. Kontrollstrukturen 12 durch die Schleife erfolgen soll. In einer do-while-schleife sind keine geschweiften Klammern notwendig. Sie werden aber der Klarheit wegen gerne verwendet! do Anweisungen while (Bedingung) Hinweis do { Anweisungen } while (Bedingung) Mit break und continue Anweisungen kann ein Programmablauf verändert werden. Diebreak Anweisung in einerwhile,for oderdo-while Schleife bewirkt einen sofortigen Ausstieg aus der jeweiligen Struktur und setzt die Programmausführung hinter der Struktur fort. Diecontinue Anweisung geht direkt zum nächsten Schleifendurchgang. 2.2.4.1. Logische Operatoren Bislang wurden nur einfache Bedingungen wie x <= 10 oder messwert!= -1 verwendet; d. h. Bedingungen, welche mit den Operatoren >, <, >=, <=, ==,!= konstruiert werden konnten. Mit den logischen Operatoren && (logisches UND), (logisches ODER) und!(logisches NICHT = Negation) lassen sich wesentlich komplexere Bedingungen erstellen. Der mathematische Term 3 < x < 7 wird mit (3 < x && x < 7) in C++ dargestellt. Obwohl die Vergleichsoperatoren <, >,... eine höhere Priorität haben als die logischen Operatoren&& und, wird ein Programm übersichtlicher, wenn in den zusammengesetzten Bedingungen Klammern gesetzt werden. Beispiel if ( geschlecht == 1 && alter >= 65) ++seniorenfrauen; Programmbeispiel #include <iostream> using namespace std; if (( geschlecht == 1) && (alter >= 65)) ++seniorenfrauen; int main (int argc, char * const argv[]) { int geschlecht = 0; int alter ; int seniorenmaenner = 0; while (geschlecht > 1){ cout << "Geschlecht (0 = w, 1 = m, 1 = Ende) "; cin >> geschlecht; if (( geschlecht == 0) ( geschlecht == 1)){ cout << "Alter " ; cin >> alter ;

2. Kontrollstrukturen 13 } } if (( alter > 65) && (geschlecht == 1)) { cout << "Das könnte ein Opa sein!" << endl; ++seniorenmaenner; } } cout << "Anzahl der Opas = " << seniorenmaenner; return 0;

2. Kontrollstrukturen 14 2.2.5. Zusammenfassung zu Kapitel 2 1. Verzweigungen: if-else und Auswahloperator?: Beispiel if ( PunktProz>=40) cout<<"pruefung bestanden!\n" ; else cout<<"pruefung wiederholen!\ n"; cout << (PunktProz >= 40? " Pruefung bestanden" : " Pruefung wiederholen"); Wenn zu einerif oderelse Verzweigung mehrere Anweisungen gehören, dann müssen diese in{...} eingeschlossen werden. 2. while-schleife Beispiel int zaehler=1; while (zaehler <=10) {cout << zaehler << endl ; zaehler++; } Die while-schleife wird so lange durchlaufen, wiezaehler<=10 ist. 3. for-schleife for ( int zaehler=1; zaehler <=10; zaehler++) cout << zaehler << endl; Die for-schleife wird so lange durchlaufen, wiezaehler<=10 ist. 4. do-while-schleife int zaehler=1; do { cout << zaehler << endldie do-while-schleife überprüft die Schleifendurchlaufbedingung erst am Ende der Schleife. ; zaehler++; }while (zaehler<=10)

2. Kontrollstrukturen 15 Die break-anweisung in einer while, for oder do-while-schleife bewirkt einen sofortigen Ausstieg aus der jeweiligen Struktur. 5. Zuweisungen Beispiele besonderer Zuweisungen a = a + 3; entsprichta += 3; Es gibt auch+=,-=,*=,/=,%=. Inkrementieren um 1 mit ++, Dekrementieren um 1 mit : a++ - Postinkrement; ++a - Präinkrement; a-- - Postdekrement; --a - Prädekrement 6. Datentypen Neben char, int und double wird vor allem für Abfragen auch der Variablentyp bool verwendet, welcher nur die Werte true (intern: 1) und false (intern 0) annehmen kann. Ein logischer Ausdruck kann in C++ ein ganz allgemeiner arithmetischer Ausdruck sein. Wenn sein Wert 0 ist, wird er alsfalse behandelt. 7. Logische Operatoren && für das logische Und für das logische Oder!= für das logische Nicht

3. Funktionen Eine Funktion erledigt eine abgeschlossene Teilaufgabe. Der Funktion können Daten übergeben werden und sie gibt das Ergebnis ihrer Aufgabe zurück. Eine Funktion muss nur einmal definiert werden. Danach kann sie beliebig oft mit ihrem Namen aufgerufen werden, um die ihr zugewiesene Aufgabe zu erledigen. Die Funktion selbst kann auch wieder Funktionen aufrufen. 3.1. Mathematische Bibliotheksfunktionen Mathematische Funktionen werden, wie auch Funktionen allgemein, normalerweise durch den Namen der Funktion, gefolgt von einem Argument oder einer Liste von Argumenten in runden Klammern aufgerufen. cout << sqrt (900.0) ruft die Standardbibliotheksfunktion sqrt auf und berechnet die Wurzel der Zahl 900.0. Um die Mathe- Bibliotheksfunktionen verwenden zu können, muss ins Programm#include <cmath> eingegeben werden. Beispiele mathematischer Standardfunktionen (x, y sind vom Typedouble): Funktion Beschreibung Beispiel sin(x) Sinusfunktion, x im Bogenmaß sin(3.1416/6) = 0.5 cos(x) Cosinusfunktion, x im Bogenmaß cos(3.1416/2) = 0.0 tan(x) Tangensfunktion, x im Bogenmaß tan(3.1416/4) = 1.0 sqrt(x) Quadratwurzel von x sqrt{900.0} = 30.0 pow(x,y) Potenzieren x y pow(9,0.5) = 3 Eine umfangreichere Liste der mathematischen Standardfunktionen findet man bei http://www.cplusplus.com/ref/cmath/. 16

3. Funktionen 17 3.2. Definition von Funktionen Im folgenden Beispiel wird inmain mitsquare(x) die Funktionsquare 10 Mal aufgerufen. Sie erhält eine Kopie des Wertes x in ihren Parameter y. Dann berechnet square den Term y*y. Das Ergebnis dieser Berechnung wird an den Punkt in main zurückgegeben, wosquare aufgerufen wurde. Der Wert vonxwird durch den Funktionsaufruf nicht geändert. Die Definition von square zeigt, dass sie einen integer-parameter y erwartet. Der Rückgabetyp des Funktionswertes ist int. In Programmzeile 3 steht der Funktionsprototyp. Der Datentypint in den runden Klammern zeigt dem Compiler an, dass die Funktion square einen int-wert vom Aufrufer erwartet. Der Datentyp int links vom Funktionsnamen, sagt dem Compiler, dass square ein integer-ergebnis zurückliefert. Der Funktionsprototyp ist nicht notwendig, wenn die Funktion vor ihrer ersten Verwendung definiert wird. 1 #include <iostream> 2 using namespace std; 3 int square( int ) ; // Funktionsprototyp 4 5 int main(int argc, char * argv[]) 6 { 7 for ( int x = 1; x <= 10; x++ ) 8 cout << square( x ) << " "; 9 10 cout << endl; 11 return 0; 12 } 13 // Definition der Quadrierfunktion 14 int square( int y ) 15 { 16 return y * y; 17 } Format fuer eine Funktionsdefinition: Rueckgabetyp Funktionsname(Parameterliste) { Funktionsblock mit Deklarationen und Anweisungen } Wird als Rückgabetyp void angegeben, dann bedeutet das, dass die Funktion keinen Wert zurückliefert. Im Funktionsblock steht dann am Ende nurreturn;.

3. Funktionen 18 Die Parameterliste ist eine durch Komma getrennte Liste mit Parameterdeklarationen (vgl. z. B.main-Funktion) Wenn eine Funktion keinen Übergabewert bekommt, dann trägt man in die runden Klammern void oder nichts ein. Beachte: Eine Funktion kann nicht innerhalb einer anderen Funktion definiert werden! 3.3. Funktionsprototypen Ein Funktionsprototyp oder eine Funktionsdeklaration, sagt dem Compiler, dass irgendwo eine Funktion mit diesem Aussehen definiert ist. Damit kennt er den Namen der Funktion bereits und kann sie ggf. aufrufen und eine Syntaxprüfung machen (vgl. 3.4. Erst wenn die Funktion definiert wird, erzeugt der Compiler den entsprechenden Code und legt den notwendigen Speicherplatz an. 3.4. Header-Dateien Jede Standardbibliothek hat eine zugehörige Header-Datei, welche die Funktionsprototypen der Bibliotheksfunktionen enthält. Beispiele: Die Headerdatei cmath enthält die Funktionsprototypen der mathematischen Bibliotheksfunktionen, so z. B. int abs (int); für die Betragsfunktion oder double sqrt (double); für die Wurzelberechnung. Die Headerdatei iostream enthält die Funktionsprototypen für die Standardein- und ausgabe. Der C++ Anwender kann eigene Headerdateien verwenden. Diese sollten (wie die alten C-Headerdateien) mit.h enden. Beispiel: #include "square.h" Beachte: Schreibe nicht <square.h>. Mit dieser Angabe würde der Compiler in einem für C++ voreingestellten Verzeichnis nach square.h suchen. An dem extrem einfachen Beispiel der Quadratzahlen soll die Struktur mit Headerdateien verdeutlicht werden. 1 // square. h Headerdatei der Quadrierfunktion 2 #ifndef SQUARE_H

3. Funktionen 19 3 #define SQUARE_H 4 int square (int) ; 5 #endif 1 // square. cpp Ausführung von square.h 2 #include "square.h" 3 int square (int n) 4 { 5 return n * n; 6 } 1 // quadratzahlen. cpp 2 #include <iostream> 3 #include "square.h" 4 using namespace std; 5 6 int main(int argc, char * argv[]) 7 { 8 for ( int i = 1; i<=10; i++) 9 cout << square(i) << " "; 10 cout << endl; 11 return 0; 12 } Die Compileranweisungen #ifndef SQUARE_H #define SQUARE_H... #endif sind Anweisungen an den Präprozessor. Sie bewirken, dass, wenn SQUARE_H definiert ist, kein weiteres Mal Programmcode eingelesen wird, der zwischen#ifndef und#endif steht. Wenn die Headerdatei bisher nicht eingelesen wurde, dann wird der Name SQUARE_H definiert und die Anweisungen der Headerdatei eingelesen. Es ist eine gängige Konvention, für diesen symbolischen Namen in den Präprozessoranweisungen eine Ableitung aus dem Headerdateinamen zu verwenden. Die Übersetzung der Teilprogramme sieht dann folgendermaßen aus: g++ square.cpp quadratzahlen.cpp. Sollen alle Warnungen ausgegeben werden, Debuggerinformationen mitgeliefert werden und noch der Pfad für die Includedateien angegeben werden, sieht die Anweisung für die Übersetzung folgendermaßen aus: g++ -g -Wall -I. square.cc quadratzahlen-with-header.cc

3. Funktionen 20 Steht square.cc noch nicht zur Verfügung, kann das Hauptprogramm quadratzahlen-with-header.cc dennoch übersetzt werden mit g++ -c quadratzahlen-with-header.cc. Es wird ein ObjektfilequadratZahlen-with-header.o erzeugt (vgl. 1.1.1) 3.5. Zufallszahlengenerator 3.5.1. Zufallszahlengenerator im Textfenster Die Funktion rand() erzeugt eine ganze Zufallszahl (unsigned int) zwischen 0 und RAND_MAX. Diese maximale Zufallszahl ist in der <cstdlib>-headerdatei definiert. Will man z. B. einen Würfel simulieren, dann kann man dies mit rand()%6 erreichen. Damit erhält man Zufallszahlen zwischen 0 und 5. Man braucht dann nur noch 1 dazuaddieren um die Würfelaugen darzustellen. 1 // Wuerfeln simuliert mit 1 + rand() % 6 2 #include <iostream> 3 using namespace std; 4 #include <cstdlib> 5 6 int main(int argc, char * argv[]) 7 { 8 for ( int i = 1; i <= 20; i++ ) { 9 cout << " " << ( 1 + rand() % 6 ) ; 10 if ( i % 5 == 0 ) 11 cout << endl; 12 } 13 14 return 0; 15 } Die Funktion rand erzeugt Pseudo-Zufallszahlen. Jedes Mal, wenn das Programm aufgerufen wird, erhält man jedoch die gleiche Folge von Zufallszahlen. Dies ist für die Analyse eines Programms wichtig. Erst wenn ein Programm fehlerfrei ist, kann man diese Bedingung mit der Funktion srand ausschalten. Werden der Funktion srand verschiedene positive ganze Zahlen als Argument übergeben, dann liefert rand jeweils eine andere Folge von Zufallszahlen beim Aufrufen des Programms. Eine einfache Variante der Initialisierung der Zufallszahlen erhält man durch den Funktionsaufruf srand(time(0)). Der Funktionsaufruf time(0) liefert das Kalenderdatum in Sekunden seit dem 1.1.1970, 0:0 Uhr. Die Funktiontime ist in<ctime>.

3. Funktionen 21 3.6. Übergabeparameter bei Funktionen In C++ können Funktionen auf zwei Arten Parameter übergeben werden. 3.6.1. Übergabe per Wert - call-by-value Der Wert wird kopiert und der Funktion übergeben. Innerhalb der Funktion wird mit der Kopie weitergearbeitet. Das Original bleibt unverändert erhalten. vgl. 3.2. 3.6.2. Übergabe per Referenz - call-by-reference 3.6.2.1. Definition von Referenzen Eine Referenz ist ein anderer Name ( Aliasname ) für ein bereits existierendes Objekt. Bei der Definition einer Referenz wird also kein neuer Speicherplatz belegt. Alle Operationen mit der Referenz werden mit dem Objekt durchgeführt, auf das die Referenz verweist. Die Definition einer Referenz geschieht mit dem Et-Zeichen&( Ampersand ). Ist T ein Typ, so bedeutet&t Referenz auf T. Beispiel: double x = 10.7; double& rx = x; // oder double &rx = x; rx ist ein anderer Name für die Variable x und hat den Typ Referenz auf double. Operationen mitrx wie--rx betreffen stets die Variablex. Das Zeichen&für eine Referenz kommt nur in der Deklaration vor und hat nichts mit dem Adressoperator& zu tun. Der Adressoperator liefert die Adresse eines Objekts. Eine Referenz muss bei der Deklaration initialisiert werden und ist dann nicht mehr veränderbar. Sie kann nicht dazu benutzt werden, später auf eine andere Variable zu verweisen. 3.6.2.2. Referenzen als Funktionsparameter Wenn ein übergebener Parameter modifiziert werden soll, kann die Übergabe durch eine Referenz des Objektes geschehen. Anstatt mit einer Kopie wird direkt mit dem Original gearbeitet.

3. Funktionen 22 In der Funktionsdeklaration (Prototyp der Funktion) folgt auf den Parametertyp ein&. Beim Funktionsaufruf und in der Funktion wird die übergebene Variable nur mit ihrem Namen verwendet. Dennoch wird intern mit dem Originalobjekt gearbeitet. Beispiel 1 // Vergleich call by value und call by reference 2 #include <iostream> 3 using namespace std; 4 int quadrierebyvalue( int ); 5 int quadrierebyreference( int & ); 6 7 int main() 8 { 9 int x = 2, z = 4; 10 cout << "x = " << x << " vor squarebyvalue\n" 11 << "Ergebnis von squarebyvalue: " 12 << quadrierebyvalue( x ) << endl 13 << "x = " << x << " nach squarebyvalue\n" << endl; 14 cout << "z = " << z << " vor quadrierebyreference" << endl 15 << "Ergebnis von quadrierebyreference " << quadrierebyreference( z ) 16 << endl; 17 cout << "z = " << z << " nach quadrierebyreference" << endl; 18 return 0; 19 } 20 21 int quadrierebyvalue( int a ) 22 { 23 return a * = a ; // Argument wird nicht geandert 24 } 25 26 int quadrierebyreference( int &cref ) 27 { 28 return cref * = cref ; // Argument wird veraendert 29 } 3.7. Überladen von Funktionen In C++ können Funktionen überladen werden, d. h. verschiedene Funktionen mit demselben Namen erledigen ähnliche Aufgaben, aber mit unterschiedlichen Datentypen. 1 // Ueberladen 2 #include <iostream>

3. Funktionen 23 3 using namespace std; 4 int quadriere( int x ) { return x * x ; } 5 double quadriere( double y ) { return y * y ; } 6 7 int main(int argc, char * argv[]) 8 { 9 cout << "Das Quadrat der ganzen Zahl 7 ist " << quadriere( 7 ) 10 << "\n Das Quadrat der Dezimalzahl 7.5 ist " << quadriere( 7.5 ) 11 << endl; 12 return 0; 13 } Der Compiler unterscheidet überladene Funktionen anhand ihrer Signatur. Die Signatur einer Funktion folgt aus der Anzahl und aus dem Typ der Parameter. Falls sich der Compiler nicht entscheiden kann, muss der Cast-Operator (typ) verwendet werden. So würde quadriere( 7/5 ) den Wert 1 liefern. Mit quadriere( (double)7/5) erhält man den richtigen Wert 1.96, weil 7 in double konvertiert wird. Der Cast-Operator (typ) hat eine höhere Priorität als die arithmetischen Operatoren. 3.8. Funktionstemplates Noch nicht bearbeitet!

3. Funktionen 24 3.9. Zusammenfassung zu Kapitel 3 1. Mathematische Bibliotheksfunktionen Mit #include <cmath> werden mathematische Standardfunktionen wie sin(x), cos(x), sqrt(x),... im Programm zur Verfügung gestellt. 2. Definition von Funktionen 1 #include <iostream> 2 using namespace std; 3 int square( int ) ; // Funktionsprototyp 4 int main(int argc, char * argv[]) 5 { 6 for ( int x = 1; x <= 10; x++ ) 7 cout << square( x ) << " "; 8 cout << endl; 9 return 0; 10 } 11 // Definition der Quadrierfunktion 12 int square( int y ) 13 { 14 return y * y; 15 } Kein Rückgabewert: Kein Übergabewert: 3. Zufallszahlengenerator z. B. void quadrierebyreference(int &cref) z. B. int werfe2wuerfel(void) oder int werfe2wuerfel() 1 #include <iostream> 2 using namespace std; 3 #include <cstdlib> 4 /* enthaelt die Funktionen rand() und srand() fuer die 5 Zufallszahlen. rand() gibt eine Zufallszahl zwischen 0 und 6 RAND_MAX */ 7 #include <ctime> // liefert die Funktion time () 8 9 int main(int argc, char * argv[]) 10 { 11 srand(time(0)); 12 /* time(0) liefert die Anzahl der Sekunden seit 1.1.1970 13 Bei jedem Aufruf des Programms liefert srand() mit 14 rand() eine neue Zufallsfolge */

3. Funktionen 25 15 for ( int i = 1; i <= 10; i++ ) { 16 cout << 1 + rand() % 6; // Zufallszahl zwischen 1 und 6 17 } 18 return 0; 19 } 4. Funktionsparameter call-by-value:der Übergabeparameter bleibt unverändert! call-by-reference:der Übergabeparameter kann modifiziert werden! 1 #include <iostream> 2 using namespace std; 3 int quadrierebyvalue( int ) ; // Prototyp 4 void quadrierebyreference( int & ); // Prototyp 5 6 int main(int argc, char * argv[]) 7 { 8 int x = 2, z = 4; 9 cout << "x = " << x << " vor squarebyvalue\n" << "Ergebnis von 10 squarebyvalue: " 11 << quadrierebyvalue( x ) << endl 12 << "x = " << x << " nach squarebyvalue\n" << endl; 13 cout << "z = " << z << " vor quadrierebyreference" << endl; 14 quadrierebyreference( z ); 15 cout << "z = " << z << " nach quadrierebyreference" << endl; 16 return 0; 17 } 18 int quadrierebyvalue( int a ) 19 { 20 return a * = a ; // Argument wird nicht geaendert 21 } 22 void quadrierebyreference( int &cref ) 23 { 24 cref * = cref ; // Argument wird veraendert 25 } 5. Überladen von Funktionen Funktionen mit gleichem Funktionsnamen, aber unterschiedlichen Datentypen können überladen werden. 1 #include <iostream> 2 using namespace std; 3 int quadriere( int x ) { return x * x ; }

3. Funktionen 26 4 double quadriere( double y ) { return y * y ; } 5 6 int main(int argc, char * argv[]) 7 { 8 cout << "Das Quadrat der ganzen Zahl 7 ist " << quadriere( 7 ) 9 << "\n Das Quadrat der Dezimalzahl 7.5 ist " << quadriere( 7.5 ) 10 << endl; 11 return 0; 12 }

4. Arrays Ein Array besteht aus aufeinanderfolgenden Speicherplätzen, die alle den gleichen Namen haben und vom gleichen Datentyp sind. Um auf einen solchen Speicherplatz zuzugreifen, gibt man den Namen des Arrays und die Positionsnummer des Arrayelements an. feld_c[0] -46 feld_c[1] 5 feld_c[2] 0 feld_c[3] 39 feld_c[4] 1543 feld_c[5] -76 feld_c[6] 0 feld_c[7] 54 feld_c[8] -8 feld_c[9] 2 feld_c[10] 456 feld_c[11] 339 Die nebenstehende Skizze zeigt ein Array feld_c mit ganzen Zahlen. Es hat 12 Elemente. Das erste Element in einem Feld hat stets die Nummer 0. Somit wird das erste Element mit feld_c[0], das zweite Element mit feld_c[1] und das 6. Element mit feld_c[5] erreicht. Allgemein greift man auf das n-te Element mit feld_c[n-1] zu. Man nennt die Positionsnummer Index des Feldes. Um z. B. die Summe der Zahlen in den ersten drei Arrayelementen auszugeben, kann man die C++ Anweisung cout << feld_c [0] + feld_c [1] + feld_c [2] << endl; schreiben. 4.1. Deklaration von Arrays Das Feld feld_c mit zwölf Elementen vom Typ Integer wird auf folgende Weise deklariert: int feld_c [12]; 4.2. Beispiele mit Arrays 4.2.1. Initialisieren eines Arrays 1 #include <iostream> 2 #include <iomanip> 27

4. Arrays 28 3 using namespace std; 4 5 int main(int argc, char * argv[]) 6 { 7 const int arraysize = 10; // d.h. die Feldgroesse soll unveraenderbar sein 8 int j, s [ arraysize ]; 9 double neu[arraysize]={0}; 10 for ( j = 0; j < arraysize ; j ++ ) // Werte der Arrayelemente festlegen 11 s [ j ] = ( j+1) * ( j+1); 12 cout << setw(15) << "Arrayelement" << setw(10) << "Wert" << endl; 13 for ( j = 0; j < arraysize ; j ++ ) // Ausgabe des Arrays 14 cout << setw(15) << j << setw(10) << s [ j ] << endl; 15 for ( j = 0; j < arraysize ; j ++ ) // Werte der Arrayelemente festlegen 16 neu[ j ] = 100.0/( j+1); 17 cout << setw(15) << "Arrayelement" << setw(15) << "Wert" << endl; 18 for ( j = 0; j < arraysize ; j ++ ) // Ausgabe des Arrays 19 cout << setw(15) << j << setw(15) << setprecision(8) << showpoint << neu[ j ] << endl; 20 21 return 0; 22 } Hinweise: Mit dem Schlüsselwort const, können Read-Only -Objekte angelegt werden. Eine solche Deklaration ist immer dann zu empfehlen, wenn Objekte nur als Konstante benutzt werden sollen, d. h. nachträglich nicht verändert werden sollen. Hier wird arraysize statt der direkten Angabe der Konstanten 10 verwendet. Die Verwendung von Konstanten bei der Festlegung von Feldgrößen macht Programme leichter korrigierbar, da nur an einer Stelle im Programm die Feldgröße durch die Konstante festgelegt wird. Formatierung und Manipulatoren Werden Arraywerte ausgegeben, dann ist es oft hilfreich die Feldbreite mit setw(int n) zu setzen. Dieser und andere Manipulatoren verlangen die Headerdatei iomanip. Weitere hilfreiche Formatierungsanweisungen und Manipulatoren: setprecision(int n) Setzt die Genauigkeit aufn showpoint Dezimalpunkt und abschließende Nullen werden gezeigt. fixed Die insetprecision angegebenen Stellen werden als Nachkommastellen eingesetzt. scientific Dezimalzahlen werden in exponentieller Schreibweise ausgegeben. Die Elemente eines Arrays können auch direkt bei der Deklaration mit einer Liste von

4. Arrays 29 durch Komma getrennten Werten initialisiert werden. Im folgenden Programm wird das Integer-Array mit 10 Zahlenwerten initialisiert und danach ausgegeben. 1 #include <iostream> 2 using namespace std; 3 4 int main(int argc, char * argv[]) 5 { 6 int n [10]={12,15,19,34,29,67,34,13,90,42}; 7 // statt n[10] ist auch n [] moeglich 8 cout << "Arrayelement" << " " << "Wert" << endl; 9 for ( int i = 0; i < 10; i++ ) // Array ausgeben 10 cout << i << " " << n[ i ] << endl; 11 12 return 0; 13 } Wenn in der Liste weniger Initialisierungselemente als für das Array erforderlich enthalten sind, dann werden die restlichen Arrayelemente mit 0 initialisiert. Dadurch kann z. B. das Arraynmit int n [10] = {0}; in allen 10 Elementen mit 0 initialisiert werden. int n [10] = {}; liefert ebenfalls in allen 10 Elementen eine 0. Diese Anweisung ist aber nicht so aussagekräftig. Wenn bei der Deklaration eines Feldes die Feldgröße nicht angegeben wird, dann bestimmt sie sich aus der Anzahl der Initialisierungselemente, z. B. n [] = {1,4,5,3,7} deklariert und definiert ein Feldnmit fünf Elementen. 4.2.2. Verteilung der Augenzahl beim Würfeln Im Abschnitt 3.5 wurde der Zufallsgenerator eingeführt. Eine Häufigkeitsverteilung kann mit Hilfe eines Arrays elegant bestimmt werden. 4.2.2.1. Häufigkeitsverteilung im Textfenster 1 // Wuerfle 10000 Mal 2 #include <iostream> 3 #include<iomanip> 4 #include <cstdlib>

4. Arrays 30 5 #include <ctime> 6 using namespace std; 7 8 int main() 9 { 10 const int wurfzahl = 10000; // wuerfle 10000 11 const int arraysize = 7; // wir nehmen nur die Indizes 1 bis 6 12 int Haeufigkeit[arraySize ] = {0}, Augenzahl; 13 srand(time(0)) ; // zufaellig verteile Wuerfelfolgen 14 for ( int anz = 1; anz <= wurfzahl; anz++ ) { 15 Augenzahl = 1 + rand() % 6; 16 ++Haeufigkeit[Augenzahl]; 17 } 18 cout << setw(10) << "Augenzahl" << setw(15) << "Haeufigkeit" << endl; 19 for ( Augenzahl =1; Augenzahl < arraysize; Augenzahl++) 20 cout << setw(10) << Augenzahl << setw(15) << Haeufigkeit[Augenzahl] << endl; 21 22 return 0; 23 } 4.3. Übergabe von Arrays an Funktionen Um ein Array an eine Funktion als Argument zu übergeben, ist nur der Name des Arrays (ohne Klammern) und die Größe des Arrays anzugeben. Im folgenden Programmbeispiel wird die Übergabe eines Arrays und eines Arrayelements an eine Funktion gezeigt. 1 // Uebergabe von Arrays und einzelnen Arrayelementen an Funktionen 2 #include <iostream> 3 #include <iomanip> 4 using namespace std; 5 void modiarray( int [], int ) ; // Feldname und Feldgroesse 6 void modielement( int ); 7 8 int main(int argc, char * argv[]) 9 { 10 const int arraysize = 5; 11 int i, a [ arraysize ] = { 0, 1, 2, 3, 4 }; 12 cout << "Effekte bei der Uebergabe eines ganzen Arrays (call by reference )" 13 << "\n\ndie Werte des originalen Arrays sind:\n";

4. Arrays 31 14 for ( i = 0; i < arraysize ; i++ ) 15 cout << setw(5) << a[ i ]; 16 cout << endl; 17 // Uebergabe des Arrays ( call by reference) 18 modiarray( a, arraysize ); 19 cout << "Die Werte des modifizierten Arrays sind:\n"; 20 for ( i = 0; i < arraysize ; i++ ) 21 cout << setw(5) << a[ i ]; 22 cout << "\n\n\n" 23 << "Effekte bei der Uebergabe eines Arrayelements (call by value):" 24 << "\n\nder Wert von a[3] ist vorher " << a[ 3 ] << \n ; 25 modielement( a[ 3 ] ) ; 26 cout << "Der Wert von a[3] ist nachher " << a[ 3 ] << endl; 27 return 0; 28 } 29 30 // In der Funktion modiarray, zeigt "b" auf das erste Element 31 // des Arrays "a" im Speicher. 32 void modiarray( int b[], int sizeofarray ) 33 { 34 for ( int j = 0; j < sizeofarray; j++ ) 35 b[ j ] * = 2; 36 } 37 38 // In der Funktion modielement, ist " e" eine Kopie des 39 // Arrayelements a [ 3 ], das von der main Funktion uebergeben wird. 40 void modielement( int e ) 41 { 42 cout << "Der Wert in der Funktion modielement ist " 43 << ( e * = 2 ) << endl; 44 } Hinweise: Funktionskopf vonmodiarray bei der Definition: void modiarray(int b[], int arraysize) Damit wird angezeigt, dass modiarray die Adresse eines Arrays von Integerwerten im Parameter b und die Anzahl der Arrayelemente im Parameter arraysize erwartet. Die Größe des Arrays zwischen den Klammern [] ist nicht notwendig. Wenn sie dort eingefügt wird, ignoriert sie der Compiler. Der Prototyp sieht noch sonderbarer aus:

4. Arrays 32 void modiarray(int [], int ) Wird in der Funktion void modielement(int e) eine Referenz mit void modielement(int& e) übergeben, wird das Arrayelement geändert. 4.4. Mehrdimensionale Felder Zwei-, drei- und mehrdimensionale Felder werden in C++ linear abgebildet. Bei einem zweidimensionalen Feld kommen zuerst alle Elemente der ersten Zeile, dann alle Elemente der zweiten Zeile usw. 1 // zweidimensionales Array ausgeben 2 #include <iostream> 3 using namespace std; 4 5 int main(int argc, char * argv[]) 6 { 7 const int dim1=2, dim2=3; // 2 Zeile, 3 Spalten 8 int matrix[dim1][dim2 ]= {{1,2,3},{4,5,6}}; 9 10 11 for(int i=0;i<dim1;i++) 12 { 13 for(int j =0; j<dim2;j++) 14 cout<<matrix[i][j]<<" "; 15 cout << endl; 16 } 17 } Die Konstanten dim1 und dim2 müssen zur Compilationszeit bekannt sein. Mehrdimensionale Arrays haben für jede Dimension ein Klammerpaar [ ]. In C++ darf der Zugriff auf ein Element eines mehrdimensionalen Arrays nicht mit einem Komma abgekürzt werden, wie es in anderen Programmiertsprachen manchmal der Fall ist. Es darf nicht a[2,3] geschrieben werden, sondern es muss a[2][3] heißen.

4. Arrays 33 4.5. Zusammenfassung zu Kapitel 4 1. Deklaration und Initialisierung von Arrays Das erste Element in einem Feld hat den Index 0. const int arraysize = 10; int j, s [ arraysize ]; for ( j = 0; j < arraysize ; j ++ ) s [ j ] = 2 + 2 * j ; // Werte der Arrayelemente festlegen Hier wird das Feld s[] mit 10 Elementen deklariert und in einer for-schleife initialisiert. Weitere Möglichkeiten der Arrayfestlegung: int n [10]={12,15,19,34,29,67,34,13,90,42}; int n[10]={0}; initialisiert alle 10 Elemente mit 0. n []={1,4,5,3,7}; deklariert und definiert ein Feldnmit 5 Elementen. 2. Übergabe von Arrays an Funktionen C++ überträgt Arrays an Funktionen automatisch mit call-by-reference (vgl. 3.6.2), d. h. die aufgerufene Funktion kann die originalen Arrayelemente verändern. Der Wert des Arraynamens ist die Adresse des ersten Arrayelements. Funktionskopf vonmodiarray bei der Definition: void modiarray(int b[], int arraysize) Damit wird angezeigt, dass modiarray die Adresse eines Arrays von Integerwerten im Parameter b und die Anzahl der Arrayelemente im Parameter arraysize erwartet (z. B. modiarray(a,10);) Die Größe des Arrays zwischen den Klammern[] ist im Funktionskopf nicht notwendig. Der Prototyp lautet: void modiarray(int [], int ) 3. Mehrdimensionale Felder Zwei-, drei- und mehrdimensionale Felder werden in C++ linear abgebildet. Bei einem zweidimensionalen Feld kommen zuerst alle Elemente der ersten Zeile, dann alle Elemente der zweiten Zeile usw. const int dim1=2, dim2=3; // 2 Zeile, 3 Spalten int matrix[dim1][dim2 ]= {{1,2,3},{4,5,6}}; Mehrdimensionale Arrays haben für jede Dimension ein Klammerpaar [ ]. Es darf nicht a[2,3] geschrieben werden, sondern es muss a[2][3] heißen.

5. Dateiverarbeitung 5.1. Dateioperationen Um Daten permanent zu speichern, müssen sie in einer Datei auf dem externen Speicher abgelegt werden (Festplatte, Diskette,... ). Einzelne Zeichen oder Zeichenfolgen können so wie auf den Bildschirm auch in eine Textdatei geschrieben werden. Häufig werden jedoch Datensätze in einer Datei gespeichert. Ein Datensatz enthält Daten, die logisch zusammengehören, z. B. die Daten einer Person. Eine Datei ist aus der Sicht eines C++-Programms eine Folge von Bytes. Jedes Zeichen in einer Datei hat eine Byte-Position: Das erste Byte hat die Position 0, das zweite die Position 1,.... Die aktuelle Dateiposition ist die Position des Bytes, welches als nächstes gelesen oder geschrieben wird. Mit jedem übertragenen Byte erhöht sich die aktuelle Dateiposition automatisch um 1. Beim sequentiellen Zugriff werden Daten stets nacheinander gelesen oder geschrieben. Die erste Leseoperation beginnt stets am Anfang der Datei. Soll eine bestimmte Information aus einer Datei geholt werden, muss also der Dateiinhalt vom Dateianfang an der Reihe nach durchsucht werden. Beim Schreiben kann eine neue Datei erzeugt oder eine vorhandene Datei überschrieben werden. Es können auch neue Daten an das Ende einer vorhandenen Datei angefügt werden. Für einen gezielten Zugriff auf bestimmte Daten der Datei ist es notwendig, die aktuelle Dateiposition beliebig setzen zu können. Dies ermöglichst der sogenannte wahlfreie Dateizugriff. 5.1.1. File-Stream-Klassen Um mit C++ Dateien verarbeiten zu können, müssen die Header-Dateien <iostream> und <fstream> ins Programm eingefügt werden. Die Headerdatei <fstream> enthält die Definitionen der Klassen ifstream (input file stream) zum Lesen von Dateien. ofstream (output file stream) zum Schreiben in Dateien. 34

5. Dateiverarbeitung 35 fstream (file stream) zum Lesen und Schreiben von Dateien. Dateien werden geöffnet, indem man ein Objekt vom Typ einer dieser Stream-Klassen erzeugt. 5.1.1.1. ASCII-Dateien ASCII-Dateien sind mit einem Texteditor lesbar. Dafür dauert das Lesen und Schreiben von ASCII-Dateien länger als binäres (vgl. 5.1.1.2 ) Schreiben oder Lesen von binären Dateien, weil Umformatierungen vom internen Format nach ASCII (oder umgekehrt) notwendig ist. Bei ASCII-Dateien können wie bei Bildschirmein- und ausgaben die Operatoren >> und << zur Ein- und Ausgabe verwendet werden. Beispiel: 1 // Schreiben einer Matrix als ASCII Datei 2 #include<iostream> 3 #include<fstream> 4 using namespace std; 5 6 int main(int argc, char * argv[]) 7 const int Zeilen = 10, 8 Spalten = 8; 9 double Matrix[Zeilen][Spalten]; 10 11 // Matrix mit Werten fuellen 12 for(int i = 0; i < Zeilen; ++i ) 13 for(int j = 0; j < Spalten; ++j ) 14 Matrix[i][ j ] = i +1 + ( j+1)/1000.0; 15 // Schreiben als ASCII Datei (lesbar mit Editor ) 16 ofstream Ziel; 17 Ziel. open("matrix.asc"); 18 if (! Ziel) { 19 cerr << "Datei kann nicht geoeffnet werden!\n"; 20 exit (1) ; 21 } 22 23 // formatiertes Schreiben 24 for(int i = 0; i < Zeilen; ++i ) 25 { for(int j = 0; j < Spalten; ++j ) { 26 Ziel. width(8); // in ein Feld der Breite 8 wird rechtsbuendig geschrieben

5. Dateiverarbeitung 36 27 Ziel << Matrix[i][ j ]; 28 } 29 Ziel << endl; 30 } 31 Ziel. close () ; 32 } Hinweise: Stattofstream Ziel; Ziel.open("matrix.asc"); kann auch direktofstream Ziel("matrix.asc"); geschrieben werden. Neben dem Dateinamen können auch ios-flags hinzugefügt werden. Bei ofstream wird vom Compiler automatisch das Flag ios::out hinzugefügt. Es wäre auch das Flagios::app möglich, um Daten an das Ende der Datei anzufügen: Ziel.open("matrix.asc", ios::app); 5.1.1.2. Binärdateien Im Gegensatz zur formatierten Ein-Ausgabe mit den Operatoren << und >> ist der binäre Datentransfer unformatiert. Die Daten werden in der internen Darstellung direkt geschrieben bzw. gelesen, eine Umwandlung einerdouble-zahl in eine Folge von ASCII-Ziffernzeichen unterbleibt. Auf diese Art beschriebene Dateien können nicht sinnvoll mit einem Texteditor bearbeitet oder direkt ausgedruckt werden. Die zum binären Datentransfer geeigneten Funktionen in C++ sindread() undwrite(). Das Prinzip: Es wird ein Zeiger (vgl. 6.2) auf den Beginn des Datenbereichs angegeben. Dabei wird der Zeiger in den Datentyp char* umgewandelt. write() verlangt an dieser Stelle char*, weil ein char einem Byte entspricht. Zusätzlich wird die Anzahl der zu übertragenen Bytes angegeben. Zur Wandlung des Zeigers wird der reinterpret_cast-operator verwendet. Dieser Operator verzichtet auf jegliche Verträglichkeitsprüfung, weil hier Zeiger auf beliebige, d. h. auch auf selbst geschriebene Datentypen in den Typchar* umgewandelt werden sollen. Die Dateigröße bestimmt sich aus der Größe und Anzahl der ausgegebenen Daten und hat nichts mit ihrer ASCII-Darstellung zu tun, die je nach Formatierung auf verschiedene Art möglich ist. Große Dateistrukturen können ohne Benutzung von Schleifen mit einer einzigen Anweisung ausgegeben werden. Beispiel: Schreiben und Lesen einer Binärdatei 1 // Schreiben und Lesen einer Binaer Datei