• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Script hydroinformatik i
 

Script hydroinformatik i

on

  • 1,426 views

 

Statistics

Views

Total Views
1,426
Views on SlideShare
1,426
Embed Views
0

Actions

Likes
0
Downloads
0
Comments
0

0 Embeds 0

No embeds

Accessibility

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Script hydroinformatik i Script hydroinformatik i Document Transcript

    • Version 2.01 - 27. April 2010 Hydroinformatik I ”C++ und Visual C++”Olaf Kolditz und Bastian Kolditz TU Dresden / UFZ Leipzig Angewandte Umweltsystemanalyse Umweltinformatik SS 2010 c OGS Publisher 2010
    • 2VorlesungskonzeptEin wesentlicher Bestandteil der Hydroinformatik ist die Informationsverarbei-tung. Typische Hydrodaten sind z.B: digitale Gel¨ndemodelle (DGM), Nieder- aschlagsmessungen, Wasserpegel, Bodentemperaturen, Bodenkarten (Bodenty-pen), geologische Schnitte u.v.a. (s. Abb. 1 und 2) Abbildung 1: Informationsverarbeitung in der Hydrologie - DatentypenEine grundlegende Methodik f¨ r die Informationsverarbeitung ist die wissen- uschaftliche Programmierung. Daher besch¨ftigen wir uns im ersten Semester ader Veranstaltung ’Hydroinformatik’ mit der objekt-orientierten Programmie-rung in C++.Es gibt zwei M¨glichkeiten eine Programmiersprache zu erlernen: mehr theore- otisch oder mehr praktisch. Wir beschreiten den zweiten Weg. Das heißt anhandvon dem, was wir f¨ r das Programmieren ben¨tigen, erarbeiten wir uns die u oTheorie. Unser Motto ist ’Learning by doing’.
    • 3.Abbildung 2: Informationsverarbeitung in der Hydrologie - Beispiel aus der Hy-drogeologieOrganisatorischesDie Pr¨ fung ’Hydroinformatik I’ (erstes Semester) ist eine Klausur. Die Pr¨fung u u’Hydroinformatik II’ (zweites Semester) besteht aus zwei Teilen, einer Klausurund einer Programmier-Hausarbeit. Bei den Klausuren geht es um die Beant-wortung von Verst¨ndnisfragen (siehe Testfragen zu jeder Vorlesung). aSprache: normalerweise in Deutsch. Da die Syntax von Computersprachen (wieC++) immer in Englisch ist, w¨ rde ich auch mal eine Vorlesung in Englisch uanbieten.Konsultationen: immer nach der Vorlesung (Freitag ab 11 Uhr).Kontakt: jederzeit by e-mail (olaf.kolditz@ufz.de), in dringenden F¨llen auch aper Handy (0151 52739034), ich empfehle auch eine mailing Liste der Studentenanzulegen, wenn alle damit einverstanden sind.Vorlesungsunterlagen: lege ich erstmal auf meinem UFZ Server ab(http://www.ufz.de/index.php?de=11877).
    • 4Es gibt viele und sehr gute C++ B¨ cher. Bei Amazon finden sie locker uber u ¨50 C++ B¨ cher (Abb. 3). Sehr gut finde das Buch von Prinz & Prinz ”C++ u- Lernen und professionell anwenden”, da es eine gute Kombination aus Theo-rie und Programm-Beispielen ist. Zu diesem Lehrbuch gibt es auch ein extra¨Ubungsbuch. Unsere Vorlesung lehnt sich an dieses Buch an. Abbildung 3: C++ LiteraturDas heisst, etwas anders wird unsere Vorgehensweise sein. Im ersten Semesterwollen wir zielgerichtet die C++ Grundlagen anhand der Entwicklung einereinfachen ’Datenbank’-Anwendung erlernen - learning-by-doing - und die Datenschließlich in einer graphischen Benutzerschnittstelle (GUI) sichtbar machen.Somit besch¨ftigen wir uns auch zielgerichtet mit den Grundlagen von Visual aC++.Das Vorlesungskonzept: • Zielgerichtetes Erlernen der C++ Grundlagen, • Entwicklung einer ’Datenbank’-Anwendung, • Umsetzung in eine graphische Benutzerschnittstelle (Visual C++, C++ GUI), siehe Abb. 4.
    • 5. Abbildung 4: Vorlesungs-KonzeptDie Implementierung des Dialogs in Abb. 4 ist das erste greifbare Ziel der Ver-anstaltung Hydroinformatik I. In dieser GUI-Anwendung k¨nnen sie (fast) alles, owas wir lernen werden, wiederfinden: Datentypen, Ein- und Ausgabe mit ver-schiedene Ger¨ten (Tastatur, Bildschirm, Dateien), Klassen, Vererbung, Con- atainer (Listen, Vektoren) und graphische Programmierung unter Windows. Eslohnt sich also dranzubleiben ...
    • Part IC ++ Basics
    • Kapitel 1Einfuhrung ¨ 7
    • 8 ¨ KAPITEL 1 EINFUHRUNG1.1 HistorischesDie Programmiersprache C++ wurde von dem d¨nischen Informatiker Bjar- ane Stroustrup in den Bell Labs des nordamerikanischen Telekommunikations-konzerns AT&T (American Telephone & Telegraph Corporation) ab 1979/80entwickelt. C++ stellt eine Weiterentwicklung der ebenfalls von AT&T ent-wickelten, Programmiersprache C dar. Die Programmiersprache C wurde alsGrundlage f¨ r C++ aufgrund seiner effizienten Codeverarbeitung und einfachen u¨Ubertragbarkeit auf anderen Plattformen verwendet. C wurde in C++ nach demVorbild der Programmiersprache Simula-67 (1967), der ersten objektorientiertenProgrammiersprache, im Wesentlichen um ein Klassenkonzept, d.h. die Abbil-dung von Objekten in verschiedenen Klassen mit unterschiedlichen Attributen,erweitert. Daher wurde C++ zun¨chst unter dem Namen ’C mit Klassen’ (C awith classes) entwickelt. Der Name C++ wurde 1983 von Rick Mascitti erst-mals angewandt. Dabei ist das ++ eine Andeutung an den Inkrement-Operator(Inkrement: Erh¨hung einer Variable um 1), der die Verbesserungen gegen¨ ber o udem Vorg¨nger C zum Ausdruck bringen soll. Im Jahr 1985 erschien die erste aVersion von C++, die eine wichtige Grundlage f¨ r die weitere Entwicklung und uStandardisierung von C++ darstellte, da die Sprache zu dieser Zeit noch nichtakzeptiert war. Im Jahre 1989 erschien die erweiterte Version 2.0 von C++.In den 90er Jahren begann nun der Standardisierungs- und Vereinheitlichungs-prozess von C++, der eingeleitet wurde durch das Buch ’The Annotated C++Reference Manual’ (1990) von Margaret Ellis und Bjarne Stroustrup. Die ge-normte Fassung von C++ erschien 1998 (ISO/IEC 14882:1998), die 2003 miteiner neuen Version (ISO/IEC 14882:2003) nochmals nachgebessert wurde. Abbildung 1.1: Bjarne Stroustrup (http://www.research.att.com/bs/)
    • 1.2 PARADIGMEN 91.2 ParadigmenProgrammier-Paradigmen sind sogenannte Leitlinien / Konzepte f¨ r die Ge- ustaltung von Programmen, diese k¨nnen durch entsprechende Sprachmittel un- oterst¨ tzt werden. Allerdings bedeutet die Benutzung einer objekt-orientierten uSprache nicht automatisch ein objekt-orientiertes Programm (OOP). • Prozedurales Programmieren: Welche Prozeduren ben¨tigen Sie f¨ r Ihr o u Programm ? Verwenden Sie die optimalen Algorithmen. • Modulares Programmieren: Welche Module ben¨tigen Sie f¨ r Ihr Pro- o u gramm ? Strukturieren Sie Ihr Programm entsprechend modular. Die Da- ten sollten in den Modulen gekapselt sein. • Objekt-orientiertes Programmieren: Welche Klassen ben¨tigen Sie f¨ r Ihr o u ¨ Programm ? Uberlegen Sie, welche Gemeinsamkeiten die Klassen haben, benutzen Sie das Konzept der Vererbung. • Datenabstraktion: Welche Datentypen ben¨tigen Sie f¨ r Ihr Programm ? o u Erstellen Sie f¨ r jeden benutzerdefinierten Typen m¨glichst viele Opera- u o tionen.
    • 10 ¨ KAPITEL 1 EINFUHRUNG. Abbildung 1.2: Objekt-orientiertes Programmieren - OOPDie Abb. 1.2 soll das Konzept des Objekt-Orientierten Programmierens (OOP)mal aus einer anderen Sichtweise erl¨utern. Normalerweise bedeutet die Pro- agrammentwicklung (prozedural und modular) eine stetige Erweiterung des Co-des (Abb. oben). Irgendwann ist das Programm dann so un¨ bersichtlich ge- uworden, dass eigentlich niemand mehr durchblickt. Die grundlegenden Idee vonOOP dagegen sind, dass, erstens Objekte (logische Einheiten des Programms)streng gekapselt sind (sich also nicht gegenseitig beeinflussen) und, zweitens,dass es ganz schmale Schnittstellen zwischen diesen Objekten gibt (z.B. nuruber eine Adresse (sogenannte pointer)) (Abb. unten). Nat¨ rlich wachsen auch¨ udiese Objekte weiter und stoßen irgendwann an Grenzen ...Ein Beispiel aus der Praxis unserer eigenen Programmentwicklung OpenGeo-Sys. Die Abb. 1.3 zeigt das objekt-orientierte Konzept der Kernels von Open-GeoSys zur L¨sung von partiellen Differentialgleichungen. Letztlich f¨ hren alle o unumerischen Methoden zur L¨sung von linearen Gleichungssystemen Ax = b. oDaher haben wir ein Objekt konstruiert (PCS von ProCesS), das die Aufgabeubernimmt, alle Bausteine f¨ r die Assemblierung und L¨sung der Gleichungs-¨ u osysteme einzusammeln. Dabei geht es um geometrische (Punkte, Polylinien,Fl¨chen, Volumen), topologische (Element-Netze), numerische und physikali- asche Daten (z.B. Materialeigenschaften, Anfangs- und Randbedingungen). Ent-scheidend f¨ r die Machbarkeit eines objekt-orientierten Konzepts ist, dass der uAlgorithmus zum Aufstellen und L¨sen der Gleichungssysteme vollkommen ounabh¨ngig von dem spezifischen physikalischen Problem ist. Die Basisklasse a
    • 1.3 COMPILER 11f¨ r das PCS-Objekt ist CProcess, davon abgeleitet werden die speziellen Klas- usen f¨ r die spezifischen Probleme (z.B. Str¨mung, Stoff- und W¨rmetransport, u o aDeformation). Wenn Sie diesen Abschnitt noch mal durchlesen, sollten sie aller-dings stutzig werden, da neben dem erwarteten Begriff der Objekt-Orientierungauf der des Algorithmus auftaucht. Richtig, OpenGeoSys ist kein reines OOPsondern eine Kombination von objekt-orientierten und prozeduralen Konzepten.Anyway, der Schritt von C zu C++ (3. zur 4. Version, Abb. 1.3) bedeutete eineReduzierung des Quellcodes von 10MB auf 3MB, also um 70% !!! Abbildung 1.3: Objekt-orientiertes Konzept des Kernels von OpenGeoSys1.3 CompilerBevor wir irgendetwas programmieren k¨nnen, ben¨tigen wir zwei Werkzeuge: o oeinen Editor und einen Compiler. In der Abb. 1.4 sind die wichtigsten Schritteder Programmerstellung zu sehen.In der Computer-Welt (und deshalb auch in der Programmier-Welt) gibt es zweiverschiedene Philosophien: Microsoft (MS) und ’den Rest’. Um diesem Problem’auszuweichen’ und fair zu sein, benutzen wir Werkzeuge aus beiden Welten.Wir beleuchten dieses ’Problem’ sp¨ter noch mal, wenn wir uber Open Source a ¨Projekte (z.B. OpenGeoSys, unsere eigene Software-Entwicklung) sprechen. Wirinstallieren uns zun¨chst den GNU Compiler (Abschn. 1.3.1) und sp¨ter den MS a aCompiler (Abschn. 1.3.2) f¨ r das visuelle C++ Programmieren. u
    • 12 ¨ KAPITEL 1 EINFUHRUNG Editor Source file Header file Compiler Object file Linker Libraries Executable Abbildung 1.4: Quell-Code Kompilation1.3.1 GNUDas GNU-Projekt wurde von Richard Stallman mit dem Ziel gegr¨ ndet, ein uvollst¨ndig freies Betriebssystem, genannt GNU (GNU is not Unix), zu ent- awickeln. Bekannt geworden ist das Projekt vor allen Dingen auch durch die vonihm eingef¨ hrte GNU General Public License (GPL), unter der viele bekannte uSoftwareprojekte ver¨ffentlicht werden (Quelle: Wikipedia). oWenn ihr mehr uber das GNU Projekt erfahren wollt, schaut nach unter ¨http://de.wikipedia.org/wiki/GNU-ProjektAls Kompromiss benutzen wir cygwin (Abb. 1.5). Dass erm¨glicht uns, auch ounter Windows mit GNU Software arbeiten zu k¨nnen. Die Linux / Ubuntu o’Freaks’ haben die GNU Software automatisch mit dem Betriebssystem auf ih-rem Rechner. Die Anleitung zur Installation finden sie im Anhang, Abschn.12.2.2.2 (und wird nat¨ rlich in der Vorlesung besprochen) u
    • 1.3 COMPILER 13. Abbildung 1.5: Ein Kompromiss: cygwin1.3.2 MS Visual C++Auch die nicht-MS-Fans m¨ ssen zugeben, das MS Visual C++ Studio ist eine utolle Entwicklungsumgebung. Die wird uns enorm helfen, wenn wir uns sp¨ter amit GUI Programmierung besch¨ftigen. Die Express-Version von VC++ kann akostenlos direkt bei Microsoft unterhttp://www.microsoft.com/germany/express/download/webdownload.aspx her-untergeladen werden.1.3.3 QtAls plattformunabh¨ngiges visuelles C++ empfehle ich Qt (siehe Abschn. 11 aund 12.8)
    • 14 ¨ KAPITEL 1 EINFUHRUNG1.4 ”Hello World”Unser allererstes C++ Programm.1.4.1 GrundlagenJedes C/C++ Programm ben¨tigt eine main() Funktion oint main(){ return 0;}Die main() Funktion ist der ’Startpunkt’ eines jeden C/C++ Programms. Diewichtigsten Bausteine einer Funktion sind: • Typ (R¨ ckgabewert): int (return 0) u • Name: main • Argumente: (), man kann die main Funktion auch mit Argumenten auf- rufen, z.B. der Name der Eingabe-Datei, • Funktionsrumpf: ...Die Struktur der main() Funktion ist in der Abb. 1.6 dargestellt. function type function name function arguments int main() function start { ... function block return 0; function end } Abbildung 1.6: Struktur der Funktion main()
    • 1.4 ”HELLO WORLD” 151.4.2 Exercise E1 Abbildung 1.7: cygwin aufrufenAbbildung 1.8: cygwin drive ist /cygwin/home/user, wechseln zum Arbeitsver-zeichnis cd c:/myworkdirectory (oder copy und paste) Abbildung 1.9: slash (/) ist nicht gleich slash () ¨Die einzige C Ubung:#include <stdio.h>int main(){ printf("Hello World"); return 0;}Abbildung 1.10: Kommandozeile: gcc main.c, das Ergebnis ist a.exe, Aufruf desProgramms: ./aJetzt endlich zu C++ ...
    • 16 ¨ KAPITEL 1 EINFUHRUNG#include <iostream>using namespace std;int main(){ cout << "Hello World" << endl; return 0;}Abbildung 1.11: Kommandozeile: g++ main.cpp, mit ls den Inhalt des Verzeich-nisses ansehen, das Ergebnis ist a.exe, Aufruf des Programms: ./a1.5 Students ForumVielen Dank f¨ r Ihre Fragen zur ersten Vorlesung! uJB Der C compiler funktioniert, der C++ aber nicht: Wahrscheinlich haben sie nur den C Compiler (GCC) installiert. Die k¨nnen jederzeit cygwin o Komponenten nachinstallieren, siehe Abschn. 12.2.2.2. ¨DB Ich habe den MS VC++ installiert und kann die Ubungen nachvollziehen. Brauche ich den GNU Compiler von cygwin wirklich noch ?: Eigentlich nicht, mit MS VC++ haben sie einen kompletten Compiler mit allem drum und dran, dennoch kann ein Ausflug in die Konsolenwelt ja nicht schaden ... und sie k¨nnen sp¨ter in ihre Bewerbungen schreiben, dass sie o a auch unter Linux Programme entwickelt haben.MF Die aktuelle cygwin Installation sieht anders aus als im Skript beschrieben: [OK] Im Anhang (Abschn. 12.2.2.2) finden sie eine bessere Beschreibung der cygwin Installation. C++ und Mac: erstmal eine Adresse http://developer.apple.com/TOOLS/xcode/
    • 1.6 TESTFRAGEN 171.6 Testfragen 1. Was bedeutet das ++ im Namen der Programmiersprache C++ ? 2. Ist C++ eine standardisierte Programmiersprache ? 3. Was ist der Unterschied zwischen C und C++ ? 4. Was sind sogenannte Programmier-Paradigmen ? 5. Welche verschiedenen Programmier-Paradigmen kennen sie und worin un- terscheiden sie sich ? 6. Welches Paradigma verfolgen wir in der Vorlesung ? 7. Was ist objekt-orientierte Programmierung ? 8. Was ist ein Kompiler ? 9. Erkl¨ren sie die einzelnen Schritte bei einer Kompilierung (s. Abb. 1.4). a ¨ 10. Welchen Kompiler benutzen sie f¨ r die C++ Ubungen ? u 11. Welche Funktion ben¨tigt jedes C oder C++ Programm ? o 12. Was ist der Typ einer Funktion ? 13. Was ist eine Parameterliste einer Funktion ? 14. Was ist der R¨ ckgabewert einer Funktion ? u
    • Kapitel 2DatentypenJede Programmiersprache bietet die Verwendung elementarer Datentypen an,wie z.B. Ganzzahlen oder Gleitkommazahlen, logische Ausdr¨ cke oder Zeichen- uketten. Die Besonderheit von objekt-orientierten (OO) Sprachen ist die Erstel-lung benutzerdefinierter Datentypen. Dies war schon in der Sprache C mit sog.’typedef struct’ Typen m¨glich. OO Sprachen, wie C++, bieten aber noch mehr oan, die Verkn¨ pfung von benutzerdefinierten Datentypen mit den entsprechen- uden Methoden. Diese Konstrukte nennt man Klassen, aber darum geht es erstim n¨chsten Kapitel. Zun¨chst m¨ ssen wir uns (kurz) mit den handels¨ blichen a a u uDatentypen herumschlagen.2.1 Elementare Datentypen ¨Die nachfolgende Tabelle zeigt eine Ubersicht der elementaren Datentypen. Typ Bezeichner Erl¨uterung a Wahrheitswerte bool Wert kann true (=1) oder false (=0) sein Zeichen char Zeichen, statische Zeichenketten wchar t ’wide character type’ (≥ 2 Byte) string Dynamische Zeichenketten Ganzzahlen short Ganze Zahlen mit geringer Genauigkeit int Ganze Zahlen mit hoher Genauigkeit long Ganze Zahlen mit sehr hoher Genauigkeit Gleitpunktzahlen float Reelle Zahlen mit geringer Genauigkeit double Reelle Zahlen mit hoher Genauigkeit long double Reelle Zahlen mit sehr hoher Genauigkeit ¨ Tabelle 2.1: Ubersicht elementarer Datentypen 18
    • 2.2 SPEICHERBEDARF 192.2 SpeicherbedarfDie unterschiedlichen Datentypen werden durch den Compiler verschieden ver-arbeitet und gespeichert (Gr¨ße des ben¨tigten Speicherplatzes). o o Typ Speicherplatz Wertebereich bool 1 Byte (weniger geht leider nicht) char 1 Byte -128 bis + 127 bzw. 0 bis 255 int 2/4 Byte -32768 bis +32767 bzw. -2147483648 bis + 2147483647 short 2 Byte -32768 bis +32767 long 4 Byte -2147483648 bis + 2147483647 float 4 Byte ± 3.4E+38, 6 Stellen Genauigkeit double 8 Byte ± 1.7E+308, 15 Stellen Genauigkeit long double 10 Byte ± 1.7E+4932, 19 Stellen Genauigkeit Tabelle 2.2: Speicherbedarf elementarer DatentypenDer sizeof Operator ermittelt die ben¨tigte Speichergr¨ße f¨ r einen bestimm- o o uten Datentypen, z.B. sizeof(float) = 4: eine einfach genaue Gleitkommazahl ¨ben¨tigt 4 Byte Speicher. Wir verwenden den sizeof Operator in der Ubung E34. o2.3 Escape-SequenzenEscape-Sequenzen sind n¨ tzliche Helfer, z.B. zum Formatieren von Ausgaben uoder f¨ r die Benutzung von Sonderzeichen in der Ausgabe. u Zeichen Bedeutung Wirkung a alert (BEL) Ausprobieren b backspace (BS) eine Position zur¨ ck u t horizontal tab (HT) horizontaler Tabulator n line feed (LF) Zeilenumbruch v vertical tab (VT) vertikaler Tabulator r carriage return (CR) Zeilenumbruch 0 end of string Zeilenende ” ” Zeichen ’ ’ Zeichen ? ? Zeichen Zeichen Tabelle 2.3: N¨ tzliche Escape-Sequenzen u
    • 20 KAPITEL 2 DATENTYPEN2.4 Testfragen 1. Was ist der genaueste Datentyp in C++ ? 2. Wie groß ist der Speicherbedarf von einem string Datentyp ? 3. Mit welcher Anweisung k¨nnen wir den Speicherbedarf von elementaren o Datentypen ermitteln ? 4. Was sind Escape-Sequenzen ? 5. Was ist der Unterschied zwischen den Escape-Sequenzen n und r ? 6. Was ist die C++ Entsprechung der Klasse cout f¨ r einen Zeilenumbruch u ?
    • Kapitel 3Ein- und AusgabeEin Programm (ob prozedural, modular, objekt-orientiert) ist eigentlich nichtsweiter als eine Datenverarbeitung zwischen einer Eingabe (Input) und einerAusgabe (Output). I und O k¨nnen mehr oder weniger schick gemacht sein: o 1. I/O Standardger¨te, a 2. I/O Dateien, 3. Datenbanken (I) und Visualisierung (O).Aus didaktischen Gr¨ nden m¨ ssen wir leider mit dem Langweiligsten - I/O u uStandardger¨te - anfangen. Spannend wird’s, wenn Daten durch die Visualisie- arung ’lebendig’ werden. Die Abb. 3.1 zeigt eine professionelle Datenaufbereitungeinen Porenraummodells in unserem Labor f¨ r wissenschaftliche Visualisierung u(TESSIN-VISLab) am UFZ in Leipzig.Die iostream KlasseDie Ein- und Ausgabe in C++ erfolgt mit sogenannten Str¨men (streams). Die oI/O-Stream-Klassen (Abb. 3.2) bieten vielf¨ltige M¨glichkeiten, die wir uns in a o ¨den nachfolgenden Ubungen n¨her anschauen. a 21
    • 22 KAPITEL 3 EIN- UND AUSGABE. Abbildung 3.1: Wissenschaftliche Visualisierung ios istream ostream iostream Abbildung 3.2: I/O stream KlassenDie Klasse iostream geht durch Mehrfachvererbung aus den Klassen istreamund ostream hervor. iostream stellt damit die Funktionalit¨t beider I/O Klas- asen zu Verf¨ gung. u
    • 3.1 DIE STANDARD-STREAMS 233.1 Die Standard-StreamsEs gibt vier Standard-Streams: • cin: Standard-Eingabe uber die Tastatur, Objekt der Klasse istream ¨ • cout: Standard-Ausgabe auf dem Bildschirm, Objekt der Klasse ostream • cerr und clog: zwei Objekte der Klasse ostream f¨ r die Fehlerausgabe. uExercise E3.1:#include <iostream>using namespace std;int main(){ int zahl; cout << "Bitte eine ganze Zahl eingeben: "; cin >> zahl; cout << zahl << endl; return 0;}Die Ein- >> und Ausgabeoperatoren << transportieren die Str¨me von und zu oden Eingabe- bzw. Ausgabeger¨ten. Dabei formatieren sie die Datentypen (z.B. a ¨int in der Ubung E3.1) entsprechend den Einstellungen der Klasse ios. DieseEinstellungen k¨nnen durch Flags ver¨ndert werden (siehe n¨chsten Abschnitt). o a a3.2 Formatierte Ausgabenredmehr Beschreibung notwendig3.2.1 Formatierte Ausgabe von Ganzzahlen ¨In der nachfolgenden Ubung besch¨ftigen wir uns mit den verschiedenen Aus- agabem¨glichkeiten von ganzen Zahlen. oExercise E3.2.1:#include <iostream>using namespace std;int main(){ int zahl; cout << "Bitte eine ganze Zahl eingeben: "; cin >> zahl;
    • 24 KAPITEL 3 EIN- UND AUSGABE cout << uppercase // f¨r Hex-Ziffern u << " oktal tt dezimal t hexadezimal n " << oct << zahl << " tt " << dec << zahl << " tt " << hex << zahl << endl; return 0;}3.2.2 Formatierte Ausgabe von Gleitpunktzahlen ¨In der nachfolgenden Ubung besch¨ftigen wir uns mit den verschiedenen Aus- agabem¨glichkeiten von realen Zahlen. o Methoden Wirkung int precision(int n) Genauigkeit wird auf n gesetztExercise E3.2.2:#include <iostream>using namespace std;int main(){ double zahl; cout << "Bitte eine Gleitkommazahl eingeben: "; cin >> zahl; cout.precision(7); // auf sieben Stellen genau cout << "Standard: t" << zahl << endl; cout << "showpoint: t" << showpoint << zahl << endl; cout << "fixed: tt" << fixed << zahl << endl; cout << "scientific: t" << scientific << zahl << endl; return 0;}3.2.3 Ausgabe von Speicherbedarf ¨In dieser Ubung benutzen wir den sizeof Operator, um den Speicherbedarf vonStandard Daten-Typen zu bestimmen.Exercise E3.2.3:#include <iostream>using namespace std;int main(){
    • 3.3 TESTFRAGEN 25 cout << "TypetNumber of bytesn"; cout << "-----------------------n"; cout << "booltt" << sizeof(bool) << endl; cout << "chartt" << sizeof(char) << endl; cout << "shorttt" << sizeof(short) << endl; cout << "inttt" << sizeof(int) << endl; cout << "longtt" << sizeof(long) << endl; cout << "floattt" << sizeof(float) << endl; cout << "doublett" << sizeof(double) << endl; cout << "long doublet" << sizeof(long double) << endl; return 0;}3.3 Testfragen 1. Sind sie mit der Tab. 2.2 einverstanden ? 2. Welche Ein- und Ausgabeger¨te kennen sie ? a 3. Welche Klasse ben¨tigen wir f¨ r die Standard-Ein- und Ausgabe ? o u 4. Was ist die Basis-Klasse f¨ r alle Ein- und Ausgaben in C++ ? u 5. Mit welcher Klasse k¨nnen wir sowohl Eingabe- als auch Ausgabestr¨me o o benutzen ? 6. Welche Include-Datei ist notwendig, um mit I/O-Str¨men arbeiten zu o k¨nnen ? o 7. Wozu dient der Zusatz using namespace std; nach dem Include von Standard-Klassen, wie I/O Streams ? 8. Was bewirken die Stream-Operatoren << und >> ? 9. Was bewirken die Flags oct, dec, hex f¨ r die formatierte Ausgabe von u Ganzzahlen ? (ToDo) 10. Wie kann ich die Genauigkeit der Ausgabe von Gleikomma-Zahlen festle- gen ? 11. Wie kann man den Speicherbedarf einer Variable ermitteln ? Schreiben sie die C++ Anweisung f¨ r die Berechnung des Speicherbedarfs f¨ r eine u u doppelt-genaue Gleitkomma-Zahl.
    • Kapitel 4Klassen source: TU DresdenData abstraction class CStudent properties ... Instances methods ... CStudent *m_std; Abbildung 4.1: Das Klassen-Konzept - CStudent 26
    • 4.1 DATEN-ABSTRAKTION 27Das Sprachelement der Klassen sind das entscheidende Kriterium von objekt-orientierten Konzepten und die objekt-orientierte Programmierung (OOP). Klas-sen sind eine Art Schablone f¨ r einen benutzerdefinierten Datentypen. Dar¨ ber u uhinaus enth¨lt die Klasse neben den Daten auch alle Methoden (Funktionen), aum mit den Daten der Klasse operieren zu k¨nnen. Unser Beispiel f¨ r Klassen, o udas uns im Verlaufe der Vorlesung besch¨ftigen wird, ist - wie k¨nnte es an- a oders sein - CStudent (Abb. 4.1). F¨ r die Konzipierung von Klassen spielt die uAbstraktion der Daten einer Klasse eine besonders wichtige Rolle.4.1 Daten-AbstraktionDie Abb. 4.1 illustriert uns, dass eine Abstraktion von Daten (d.h. Eigenschaf-ten) der Klasse Studenten eine durchaus vielschichtige Angelegenheit sein kann.Eine Aufstellung von Daten / Eigenschaften, die es aus ihrer Sicht zu ber¨ ck- usichtigen gilt, ist ihre n¨chste Hausaufgabe. aDer n¨chste Block zeigt ihnen das Schema der Syntax der Klassen-Definition aCStudent. Das Schl¨ sselwort f¨ r die Klassen-Definition ist class, der Name ist u uCStudent. Der Klassen-Rumpf ist in geschweifte Klammer eingebettet. Wichtigist der Abschluss mit einem Semikolon. Wie bereits erw¨hnt, eine Klasse enth¨lt a aDaten (Eigenschaften) und Methoden (Funktionen) auf den Daten. Prinzipiellgeht diese Datenabstraktion auch mit anderen Sprachen wie C. A data constructtypedef struct {...} in C can be seen as an analogue to a C++ class.Die C Version:typedef struct{ char* name_first; char* name_last; long matrikel_number;} TDStudent;TDStudent *student = NULL;Die C++ Version:class CStudent{ data: ... methods: ...};Bei der Namensgebung von Klassen wird oft ein ’C’ (CStudent) vorangestellt,um die Bedeutung als Klasse (wesentlicher Baustein des Programm-Konzepts)herauszustellen.
    • 28 KAPITEL 4 KLASSENEin weiterer Vorzug von OO-Sprachen ist z.B. die Sichtbarkeit / Zugreifbarkeitvon Daten zu regeln. Der nachfolgende Block zeigt das Datenschutz-Konzeptvon C++ (Sicherheitsstufen): Daten k¨nnen ¨ffentlich sein (public) oder gezielt o of¨ r ’Freunde’ verf¨ gbar gemacht werden (protected) oder nur exklusiv f¨ r die u u ueigene Klasse sichtbar zu sein (private).class CStudent{ private: ... protected: ... public: ...};4.2 Klassen-DeklarationIm vorangegangenen Abschnitt haben wir uns mit der Datenabstraktion mittelsKlassen besch¨ftigt. So sollte konsequenterweise jede Klasse auch ihre eigenen - asorry - eigenen Quelldateien besitzen. Die Deklaration von Klassen erfolgt ubli- ¨cherweise in einer sogenannten Header-Datei *.h. F¨ r die Methoden / Funk- utionen der Klasse ist eine *.cpp Datei reserviert. F¨ r uns bedeutet dies, zwei uDateien anlegen: • student.h - die Deklaration der Klasse CStudent • student.cpp - die Methoden der Klasse CStudentUm mit der Klasse arbeiten zu k¨nnen, m¨ ssen wir das entsprechende Header- o uFile inkludieren. Dies erfolgt mit der Anweisung #include ”student.h” am An-fang unseres Main-Files.#include "student.h"int main{ return 0;}4.3 Instanzen einer KlasseAn dieser Stelle m¨chten wir unsere Eingangsgraphik (Abb. 4.1) erinnern. In- ostanzen sind Kopien einer Klasse mit denen wir arbeiten k¨nnen, dass heißt o
    • 4.3 INSTANZEN EINER KLASSE 29diese bekommen echten Speicher f¨r ihre Daten (die nat¨ rlich f¨ r jede Instanz u u ueiner Klasse unterschiedlich sein k¨nnen). oEs gibt zwei M¨glichkeiten, Instanzen einer Klasse zu erzeugen: o#include "student.h"void main(){ // Creating an instances of a class - 1 CStudent m_std_A; // Creating an instances of a class - 2 CStudent *m_std_B;}Der direkte und der mittels eines sogenannten Zeigers (hierf¨ r gibt ein Extra- uKapitel). Wir werden sehen, dass der zweite Weg oft der bessere ist, da wir z.B.die Initialisierung und das Speichermanagement f¨ r unsere Daten selber in die uHand nehmen k¨nnen. Dies k¨nnen wir mittels sogenannter Konstruktoren und o oDestruktoren erledigen. Damit besch¨ftigen wir uns im n¨chsten Abschnitt. a aExercise E4.3:#include "student.h"#include <iostream>using namespace std;int main(){ CStudent *m_std_cpp; // pointer to an instance cout << "E41: Instances of classes" << endl; cout << "What have we created?t : " << m_std << endl; cout << "What size has it?t : " << sizeof(m_std) << endl; TDStudent *m_std_c; // pointer to TD return 0;}-> student.h// Class definitionclass CStudent{ public: protected: private:};// Type definitiontypedef struct{} TDStudent;
    • 30 KAPITEL 4 KLASSEN4.4 Konstruktor und DestruktorWohl die wichtigsten Methoden von Klassen sind deren Konstruktoren CStudent()und Destruktoren ∼ CStudent(). Diese Funktionen haben den gleichen Namenwie die Klasse selbst. Der nachfolgende Block zeigt die Deklaration unserer er-sten beiden Klassen-Funktionen in der Header-Datei students.h.class CStudent{ public: CStudent(); // constructor ~CStudent(); // destructor};Wie sehen die Konstruktor/Destruktor-Funktionen aus.#include "student.h"CStudent::CStudent(){}CStudent::~CStudent(){}Die Konstruktor/Destruktor-Funktionen werden ’automatisch’ aufgerufen beimErzeugen (¨ ber die Zeiger-Version) und Zerst¨ren der Klassen-Instanz: u o • new ruft den dazugeh¨rigen Konstruktor auf, o • delete ruft den dazugeh¨rigen Destruktor auf. oDie Anwendung der Konstruktor/Destruktor-Funktionen ist im folgenden Quellcode-Abschnitt dargestellt.Exercise E4.4:#include <iostream>using namespace std;#include "student.h"int main(){ CStudent* m_std = new CStudent(); // instance using constructor cout << "E44: Constructor of class CStudent" << endl; cout << "What have we created? m_stdt : " << m_std << endl; cout << "What size has it?t : " << sizeof(m_std) << endl; cout << "What have we created? &m_stdt : " << &m_std << endl; cout << "What size has it?t : " << sizeof(&m_std) << endl; return 0;}
    • 4.5 DATENINITIALISIERUNG MIT DEM KONSTRUKTOR 314.5 Dateninitialisierung mit dem KonstruktorDer Klassen-Konstruktor kann dar¨ ber hinaus auch zur Initialisierung von Da- uten f¨ r die Klassen-Instanz benutzt werden. Ganz nebenbei schreiben wir unsere uerste Klassen-Funktion in der Quell-Datei der Klasse students.cpp. Wir initiali-sieren den Namen unseres ersten Studenten.Exercise E4.5:CStudent::CStudent(){ // Initializations name_first = "James"; name_last = "Bond";}Daf¨ r m¨ ssen wir die notwendigen Klassen-Variablen (member variables) f¨ r u u uden Namen bereitstellen. Praktischerweise ist es ratsam, die Daten und Metho-den der Klasse zu trennen. Unsere Klassen-Deklaration nimmt langsam Gestaltan ...#include <string>using namespace std;class CStudent{ // Data / Properties public: string name_first; string name_last; // Methods / Functions public: CStudent(); // constructor ~CStudent(); // destructor};F¨ r die Namen benutzen wir die string Klasse von C++ (auch hierzu gibt’s uein Extra-Kapitel). Um den Daten-Typ string aus dieser Klasse benutzen zuk¨nnen, m¨ ssen wir die Klasse wie folgt inkludieren. o u#include <string>using namespace std;Exercise E4.5:#include <iostream>using namespace std;#include "student.h"
    • 32 KAPITEL 4 KLASSENint main(){ CStudent* m_std = new CStudent(); // instance using constructor cout << "E45: Data initialisation by constructor of class CStudent" << endl; cout << "m_std->name_firstt : " << m_std->name_first << endl; cout << "m_std->name_lastt : " << m_std->name_last << endl; delete(m_std); return 0;}4.6 DatenschutzEine wichtige Eigenschaft der Sprache C++ ist die M¨glichkeit, Daten unter- oschiedlich sichtbar zu machen. Eingangs des Kapitels haben wir gesehen, dasses verschiedene Schl¨ sselw¨rter gibt, um Variablen zu klassifizieren: public, pro- u otected und private. Daten des Typs ’public’ sind uberall sichtbar, aus sie kann ¨von uberall im Programm zugegriffen werden - also auch ver¨ndert werden. Dies ¨ akann sehr schnell problematisch werden, wenn das Programm sehr groß ist odermehrere Programierer gleichzeitg entwickeln. Daten des Typs ’private’ sind nurf¨ r die eigene Klasse sichtbar, dass auf sie k¨nnen nur durch Klassen-eigene u oMethoden zugegriffen werden. Private data sind f¨ r andere Klassen verborgen. uNat¨ rlich gibt es noch einen Kompromiss: Mit dem Schl¨ sselwort ’protected’ u ukann man gewisse Daten f¨ r ’befreundete’ Klassen offnen. Dies ist im Wesentli- u ¨chen das Datenschutz-Konzept von C++. ¨In der folgenden Ubung sehen wir, wie man mit ’private’ data (Kontonummer)umgehen kann. Die Variable bank account ist als private Typ deklariert.class CStudent{ public: long GetBankAccount(); void SetBankAccount(long); private: long bank_account;};Die Zugriffsfunktion GetBankAccount() der Klasse CStudent gibt lediglich denWert der Variable zur¨ ck, ihr Typ ist nat¨ rlich public. Die Kontonummer kann u ualso zun¨chst nicht von ’außen’ ge¨ndert werden. a along CStudent::GetBankAccount(){ return bank_account;}
    • 4.6 DATENSCHUTZ 33void CStudent::SetBankAccount(long new_bank_account){ bank_account = new_bank_account;}Nat¨ rlich l¨sst sich auch eine Funktion schreiben, mit der man private Daten u avon außen ¨ndern kann: SetBankAccount(long). Letztlich entscheidet der Pro- agrammierer, ob dieser Zugriff zul¨ssig sein soll, wenn nicht gew¨ nscht, werden a udie Get und Set Zugriffsfunktionen einfach nicht bereitgestellt. ¨Die nachfolgende Ubung zeigt zusammenfassend den Zugriff auf private Varia-blen von Außen.Exercise E4.6:int main(){ CStudent* m_std = new CStudent(); // instance using constructor cout << "E46: Data security - using private data" << endl; cout << "m_std->GetBankAccount()t : " << m_std->GetBankAccount() << endl; m_std->SetBankAccount(987654321); // changing private data cout << "m_std->GetBankAccount()t : " << m_std->GetBankAccount() << endl; delete(m_std); return 0;}
    • 34 KAPITEL 4 KLASSEN4.7 Testfragen 1. Geben sie eine Definition von C++ Klassen mit eigenen Worten (max 5 S¨tze). a 2. Was ist ein benutzerdefinierter Datentyp ? 3. Welches Datennschutz-Konzept gibt es f¨ r Klassen ? u 4. Wozu brauchen wir zwei Dateien f¨ r Klassen, eine H (Header) Datei und u eine CPP (Quelltext) Datei ? 5. Was ist ein Inklude / Include ? 6. Was ist eine Instanz einer Klasse ? 7. Worin besteht der Unterschied zwischen den Anweisungen: CStudent m std 1 und CStudent* m std 2 ? 8. Was ist ein Konstruktor einer Klasse ? 9. Was ist das Gegenst¨ ck zum Klassen-Konstruktor ? u 10. Wie k¨nnen Daten / Variablen einer Klasse initialisiert werden ? o 11. Schreiben sie den Quelltext f¨ r den Klassen-Konstruktor und weisen sie u den Variablen name first und name last ihren eigenen Namen zu. 12. Was verbirgt sich hinter der Anweisung: CStudent* m std = new CStudent() ? 13. Was ist der Unterschied zwischen CStudent und CStudent() ? 14. Wie kann ich meine Daten gegen einen externen Zugriff sch¨ tzen ? u
    • Kapitel 5Strings ¨Wir haben schon in mehreren Ubungen den Datentyp string benutzt, ohne diesenDatentyp etwas n¨her zu beleuchten. Dieses Vers¨umnis soll in diesem Kapitel a anachgeholt werden.5.1 Die Standardklasse stringString (in Deutsch Zeichenkette) ist vielmehr als nur ein Datentyp, string ist eineStandard-Klasse in C++. String ist eine der genialsten Weiterentwicklungen desC-Datentyps char, die das Hantieren mit Zeichen und Zeichenketten zu einemKinderspiel macht, na sagen wir mal - uns das Programmierleben erheblichvereinfachen wird, wenn wir mit Zeichenketten operieren werden. So wird z.B.der erforderliche Speicherplatz f¨ r Zeichenketten automatisch reserviert und bei uVer¨nderungen angepasst. aWenn wir strings benutzen wollen, m¨ ssen den Header der string-Klasse wie ufolgt inkludieren.#include <string> // for using stringsusing namespace std; // for using standard namesWichtig ist auch die zweite Zeile using namespace std. Diese Anweisung besagt,dass wir im folgenden Standard-Namen benutzen. Sonst m¨ ssten wir vor jeder ustring-Operation noch den Zusatz std:: setzen. Zur Benutung von namespace f¨ r udie Strukturierung und Kapselung von Programmteilen gibt es sp¨ter ein Extra- akapitel (9.2.2). An dieser Stelle zeigen wir die Bedeutung von using namespacestd; in bew¨hrter Weise an einem Beispiel. aSie haben sicher schon bemerkt, dass wir bei #include manchmal eckige Klam-mern <> und manchmal G¨nsef¨ ßchen ” benutzen. Wir schauen uns dies, wie a u 35
    • 36 KAPITEL 5 STRINGSgesagt, genauer im Kapitel 9.2.2 an. Hier nur soviel, dass mit eckigen Klammern<> an Header-Dateien im Systemverzeichnis von C++ gesucht wird, w¨hrend a” benutzerdefinierte, eigene Header (z.B. student.h) kennzeichnet und somit imaktuellen Arbeitsverzeichnis (also ./) nachgeschaut wird.5.2 Operationen mit strings ¨Die nachfolgende Tabelle zeigt eine Ubersicht der wichtigsten string Operatio-nen, die wir in diesem Kapitel verwenden. Methode Erl¨uterung a .append() verl¨ngert den String a .c str() erzeugt Zeichenfeld mit dem Inhalt des Strings .clear() l¨scht den Inhalt des Strings o .compare() vergleicht Strings .erase() l¨scht Zeichen im String o .find() sucht Zeichen in einem String .insert() f¨ gt in den String ein u .length() ermittelt die L¨nge des Strings a .replace() ersetzt Zeichen im String wichtig f¨ r die Konvertierung von string zu char* u .resize() a ¨ndert L¨nge des Strings a .substr() gibt einen Substring zur¨ ck u >> Eingabeoperator f¨ r Strings u << Ausgabeoperator f¨ r Strings u getline() liest Zeichen aus der Eingabe Tabelle 5.1: string Methoden5.2.1 Initialisieren von stringsEine M¨glichkeit f¨ r die Initialisierung von strings haben wir uns bereits in o uder Exercise E4.5 angesehen bei der Verwendung von Klassen-Konstruktoren.Der Standard-Konstruktor string() erzeugt einen leeren String. Eine zweiteM¨glickeit besteht direkt bei der Deklaration des strings, wie folgt: oExercise E5.2.1:string exercise("Exercise: string initialisation");cout << exercise.length() << endl;
    • 5.2 OPERATIONEN MIT STRINGS 375.2.2 Zuweisen von strings ¨In der folgenden Ubung schauen wir uns an, wie wir mittels Tastatureingabe(Standard-Eingabe-Ger¨t) strings zuweisen und Teile von strings in andere ko- apieren zu k¨nnen. oExercise E5.2.2:#include ... // Bitte f¨gen sie die notwendigen Header selbst ein umain(){...string eingabe;string eingabe_anfang;string message("Bitte geben Sie eine Zeile mit der Tastatur ein. Schliessen Sie die Eingabe mit Enter ab");//-------------------------------------------------------------------cout << message << endl; // Ausgabe der Eingabeaufforderunggetline(cin,eingabe); // Eingabe einer Zeile uber Tastatur ¨eingabe_anfang(eingabe,0,10); // die ersten 10 Zeichen von eingabe werden nach eingabe_anfang kopiertcout << "Ihr Eingagetext: " << eingabe << endl;cout << "Die ersten 10 Zeichen des Eingagetextes: " << eingabe_anfang << endl;...}5.2.3 Verketten von stringsMit dem Operator + k¨nnen Strings miteinander verkn¨ pft werden und in einem o u ¨neuen string name kopiert. In der folgenden Ubung produzieren wird aus Vor-und Nachnamen den ganzen Namen.Exercise E5.2.3:string name;CStudent* m_std = new CStudent();name = m_std->name_first + m_std->name_last;// odername = m_std->name_first;name += m_std->name_last;Wie bekommen wir einen Zwischenraum (Leerzeichen) zwischen Vor- und Nach-namen ?5.2.4 Vergleichen von stringsOft sind Abfragen notwendig, ob gewisse Zeichenketten gefunden wurden, umdann gewisse Operationen durchzuf¨ hren. Hierf¨ r bietet die String-Klasse meh- u urere M¨glichkeiten an, z.B. den exakten Vergleich (string::compare) oder einen o
    • 38 KAPITEL 5 STRINGS ¨Teil von Zeichenketten (string::find). Die nachfolgende Ubung zeigt, wenn derNachname BOND gefunden wurde, dann wird der Vorname auf JAMES gesetzt(und nat¨ rlich der russische Geheimdienst informiert). uExercise E5.2.4:if(m_std->name_last.compare("BOND")==0){ m_std->name_first = "JAMES";} ¨Die nachfolgende Ubung zeigt, wie ein Programm beendet werden kann, wenneine bestimmte Taste gedr¨ ckt wird. Hierf¨ r werden einzelne Zeichen mit dem u uOperator == verglichen.string Taste("N");while(Taste == "J"){ cout << "Soll dieses Programm endlich beendet werden? (J/N)" << endl; getline(cin,Taste);}cout << "Programm-Ende" << endl;5.2.5 Suchen in strings ¨Diese Ubung zeigt ihnen, wie nach Zeichenketten in string suchen k¨nnen. Sie osehen, je nach Sorgfalt des Programmierers haben sie eventuell schlechte Karten,wenn ihr Vorname die Zeichenkette ’BON’ enth¨lt. aExercise E5.2.5:if(m_std->name_last.find("BON")!=string::npos){ m_std->name_first = "JAMES";}5.2.6 Einfugen in strings ¨Nun benutzen wir die Einf¨ ge-Funktion von strings (string::insert), um Vor- uund Nachnamen zusammenzusetzen. Dabei ermitteln wir zun¨chst die L¨nge des a aVornamen mit string::length, setzen dann den Positionsz¨hler pos um Eins hoch a(Leerzeichen zwischen Vor- und Nachnamen) und f¨ gen dann den Nachnamen umit string::insert ein.Exercise E5.2.6:
    • 5.2 OPERATIONEN MIT STRINGS 39string name;int pos;if(m_std->name_first.find("JAMES")!=string::npos){ pos = m_std->name_first.length(); name.insert(pos+1,"BOND");}5.2.7 Ersetzen in stringsEine weitere n¨ tzliche String-Funktion ist das Ersetzen von Zeichen. In der u ¨nachfolgenden Ubung andern wir den Nachnamen. Dazu wird zun¨chst wieder ¨ adie L¨nge des Vornamens mit string::length ermittelt und dann der neue Nach- aname eingef¨gt. So k¨nnen sie ihre Spuren verwischen ... ist auch praktisch bei u oNamens¨nderungen z.B. infolge Heiraten (Beachten sie, dass Triple-Namen wie aM¨ ller-Graf-Kleditsch nicht mehr zul¨ssig sind). u aExercise E5.2.7:string name;int pos;name = "JAMES" + " " + "CHRISTIE"if(m_std->name_first.find("JAMES")!=string::npos){ pos = m_std->name_first.length(); name.replace(pos+1,"BOND");}Was passiert, wenn der neue Nachname l¨nger ist als der alte ? a5.2.8 Loschen in strings ¨Nat¨ rlich k¨nnen auch Zeichen in einem string gel¨scht werden. Diese Funktion u o opasst den Speicherbedarf des gek¨ rzten Strings automatisch an. uExercise E5.2.8:string name;int pos;name = "JAMES" + " " + "CHRISTIE"if(m_std->name_first.find("JAMES")!=string::npos){ pos = m_std->name_first.length(); name.erase(pos); name.replace(pos+1,"BOND");}Abschliessend kommen wir zu zwei weiteren Punkten, (1) das Umwandeln vonC++ strings in C char und (2) das Auslesen von string Teilen.
    • 40 KAPITEL 5 STRINGS5.2.9 Umwandeln von strings in charManchmal ist es notwendig C++ strings in C char umzuwandeln (wir ben¨tigen odies sp¨ter, wenn wir mit der MFC Klasse CStrings f¨ r grafische Benutzerober- a ufl¨chen arbeiten). Die String-Methoden c str() und data() wandeln strings in achar um. Aufgepasst, ab char m¨ ssen wir uns selber um das Speichermanage- ument k¨ mmern. ufprintf(f," %sn",name.c_str());name.clear();const char *char_string;char_string = name.data();5.2.10 Auswerten von Strings: StringstreamsStringstreams ... l¨sst sich kaum aussprechen .. es handelt sich aber definitiv anicht um stringdreams ... (sie erinnern sich an die Eingangsfolie der Vorlesung).Stringstreams sind eine sehr n¨ tzliche Sache, damit lassen sich Eingabedaten u(von Tastatur und Datei) bequem als Stream auswerten. Um Stringstreams ¨nutzen zu k¨nnen, muss die Klasse sstream inkludiert werden. Die Ubung zeigt, owie man eine eingegebene Zeile (Vor- und Nachnahme) elegant zerlegen kann.Dabei wird die eingebene Zeile zun¨chst in den stringstream kopiert, danach awird input line wie ein normaler stream ausgelesen.Exercise E5.2.10:#include <iostream>#include <string>#include <sstream>using namespace std;int main(){ string name; string name_first; string name_last; stringstream input_line; cout << "Geben Sie bitte Ihren Namen (Vor- und Nachnamen) ein: "; getline(cin,name); input_line.str(name); // Der Name wird nun zerlegt input_line >> name_first; cout << "Vorname:t" << name_first << endl; input_line >> name_last; cout << "Nachname:t" << name_last << endl; input_line.clear(); return 0;}
    • 5.3 TESTFRAGEN 415.3 Testfragen 1. Welche Klasse bietet uns C++ zur Verarbeitung von Zeichenketten an ? 2. Welchen Include ben¨tigen wir f¨ r die Arbeit mit Zeichenketten ? o u 3. Wof¨ r ist die Anweisung using namespace std n¨ tzlich ? u u 4. M¨ ssen wir selber Speicherplatz f¨ r C++ Zeichenketten (Strings) reser- u u vieren ? 5. Wie k¨nnen wir einen String, sagen wir mit der Zeichenkette ”Das ist eine o gute Frage”, initialisieren ? 6. Wie k¨nnen wir zwei Strings, ihren Vor- und Nachnahmen, miteinander o verbinden ? 7. Mit welcher string Funktion kann ich Zeichenketten miteinander verglei- chen ? 8. Schreiben sie eine Anweisung zum Vergleich der Klassen-Variable m std− >name last mit ihrem Nachnamen ? 9. Mit welcher string Funktion kann ich Zeichenketten suchen ? 10. Schreiben sie eine Anweisung zum Suchen ihres Vornamens in der Klassen- Variable m std− >name first ? 11. Mit welcher string Funktion kann ich Teile in Zeichenketten erstetzen ? 12. Wie k¨nnen wir die L¨nge von Strings ermitteln ? o a 13. Schreiben sie die Anweisungen, um ihren Nachnamen in die Zeichenkette ”JAMES BOND” nach ”JAMES” einzuf¨ gen ?u 14. Was passiert, wenn ihr Nachname l¨nger als ”BOND” ist ? a 15. Mit welcher string Funktion k¨nnen wir Zeichen in einem String l¨schen ? o o 16. Wir haben gesehen, dass es verschiedene Daten-Typen f¨ r Zeichenketten u in C, C++, MFC, .NET und Qt gibt. Zeichenketten geh¨ren zu den wich- o tigsten Daten-Typen bei der Programmierung. Wie k¨nnen wir einen C++ o string in eine C Zeichenkette (char) umwandeln ? 17. K¨nnen wir eine .NET Zeichenkette (String∧) in eine C++ Zeichenkette o (string) umwandeln ? 18. Was ist ein stringstream ? 19. Welchen Include ben¨tigen wir f¨ r die Arbeit mit Stringstreams ? o u
    • Kapitel 6Ein- und Ausgabe - IINachdem wir uns im Kapitel 3 bereits mit der Ein- und Ausgabe uber die¨Standard-Ger¨te (Tastatur und Bildschirm) besch¨ftigt haben, geht es in diesem a aTeil um die Dateiverarbeitung.6.1 Die fstream KlassenAbb. 6.1 zeigt die Hierarchie der fstream Klassen. ios istream ostream iostream ifstream ofstream fstream Abbildung 6.1: Die fstream KlassenDiese sind von den bereits bekannten ios stream Klassen abgeleitet. 42
    • 6.2 ARBEITEN MIT FILE-STREAMS 43 • ifstream: ist von istream abgeleitet f¨ r das Lesen von Dateien. u • ofstream: ist von ostream abgeleitet f¨ r das Schreiben von Dateien. u • fstream: ist von iostream abgeleitet f¨ r das Lesen und Schreiben von Da- u teien.6.2 Arbeiten mit File-Streams6.2.1 File-Streams anlegenEr¨ffnungsmodus: Um eine Datei benutzen zu k¨nnen, muss diese zun¨chst o o age¨ffnet werden. Daf¨ r gibt es verschiedene M¨glichkeiten (siehe Tab. 6.1). o u o Flag Funktion ios::in Eine (existierende) Datei wird zum Lesen ge¨ffnet. o ios::out Eine Datei wird zum Schreiben ge¨ffnet. o Existierende Inhalte werden uberschrieben. ¨ ios::app Die neuen Inhalten werden an die existierenden angeh¨ngt. a ios::trunc ¨ Eine bestehende Datei wird beim Offnen auf die L¨nge 0 gek¨ rzt. a u ios::ate Schreib- und Leseposition werden auf das Dateiende gesetzt. ios::binary Schreib- und Leseoperationen werden im Bin¨rmodus ausgef¨hrt. a u Tabelle 6.1: Er¨ffnungsmodi f¨ r Dateien o uDie default Werte sind: • ios::in f¨ r ifstream u • ios::out | ios::trunc f¨ r ofstream u6.2.2 File-Streams schließenWir wissen schon, dass es bei objekt-orientierten Sprachen immer zwei passendeDinge gibt, z.B. Klassen-Konstruktoren und -Destruktoren. So ist zu erwarten,dass es zu einer Methode ’Datei ¨ffnen’ (open()) auch eine Methode ’Datei oschließen’ gibt (close()) (Tab. 6.4)6.2.3 ¨ Ubung: Eine einfache Kopierfunktion ¨In unserer ersten Ubung zur Dateiverarbeitung schreiben wir eine einfache Ko-pierfunktion.Exercise E6.2.3: Eine einfache file copy Funktion
    • 44 KAPITEL 6 EIN- UND AUSGABE - II#include <iostream> // for using cout#include <fstream> // for using ifstream / ofstream#include <string> // for using stringusing namespace std; // namespace for std functionsint main(){ //---------------------------------------------------------------- ifstream input_file; // Instance of class ifstream input_file.open("input_file.txt"); // Open file "text_file.txt" string my_string; // Instance of class string input_file >> my_string; // Reading a string from file cout << my_string.data() << endl; // Output of string to screen //---------------------------------------------------------------- ofstream output_file; // Instance of class ifstream output_file.open("output_file.txt"); // Open file "text_file.txt" output_file << my_string; // Writing a string to a file //---------------------------------------------------------------- return 0;}Die Ein- >> und Ausgabeoperatoren << formatieren die Datentypen (z.B. int ¨in der Ubung E6.2.3) entsprechend den Einstellungen der fstream Klasse. DieseEinstellungen k¨nnen durch Flags ver¨ndert werden (siehe n¨chsten Abschnitt). o a aDie main() Funktion kann auch mit einer Parameterliste (int argc, char*argv[]) versehen werden. Die Anzahl der Parameter (argc) wird automatischerkannt. MIt jedem Leerzeichen in der Tastatureingabe entsteht ein neuer Ein-gabeparameter (Abb. 6.2).int main(int argc, char *argv[]){ ifstream input_file; // Instance of class ifstream input_file.open(argv[1]); // Open file, name from cin ofstream output_file; // Instance of class ifstream output_file.open(argv[2]); // Open file, name from cin return 0;}Die Benutzung der main Funktion mit Eingabeparametern ist in der folgendenAbbildung zu sehen. Abbildung 6.2: Die main Funktion mit Parametern
    • 6.2 ARBEITEN MIT FILE-STREAMS 456.2.4 ¨ Ubung: Ein einfacher Konverter ¨Ihre Frage nach dem Sinn der Ubung 6.2.3 ist vollkommen berechtigt, wozuein Programm schreiben, um eine Datei zu kopieren. Das kann ich doch auchmit dem Windows-Explorer oder mit cp file1 file2 machen. Richtig, abergenauso funktionieren Kopierprogramme, Windows-Explorer ruft ’unser’ Ko- ¨pierprogramm auf. Wenn wir auch nur kleine Anderungen in unserer Datei vor-nehmen wollen (z.B. eine laufenden Nummer in jede Zeile einf¨ gen), kann uns uder Windows-Explorer nicht mehr weiter helfen. Dies ist insbesondere danna¨rgerlich, wenn die Datei ziemlich groß ist ... Auch hier sagen sie zu Recht, eineNummerierung in eine gr¨ßere Datei einf¨ gen, das kann ich z.B. auch mit EX- o u ¨CEL machen. In der n¨chsten Ubung schreiben wir einen kleinen Konverter, also agenau was EXCEL im Hintergrund macht, wenn wir eine neue Spalte einf¨ gen. uExercise E6.2.4: Ein einfacher Konverterint main(){ //---------------------------------------------------------------- ifstream input_file; // Instance of class ifstream input_file.open("input.txt"); // Open file "text_file.txt" ofstream output_file; // Instance of class ifstream output_file.open("output.txt"); // Open file "text_file.txt" //---------------------------------------------------------------- char line[80]; int i=0; while(input_file.getline(line,80)) // Loop condition { output_file << i << " " << line << endl; i++; // Incrementor (+1) } //---------------------------------------------------------------- return 0;}Unser Konverter macht nichts anderes, als die Datei input.txt zu ¨ffen, nach- oeinander alle Zeilen lesen und am Anfang der Zeile eine Nummer (i) einzuf¨ gen uund dann in die neue Datei output.txt zu schreiben. ¨Was ist neu bei dieser Ubung. C++ Ding Was tut’s while() eine Kontrollstruktur f¨ r Schleifen u (solange der Ausdruck in () wahr (true) ist wird die Schleife ausgef¨hrt) u i++ der Inkremetor (z¨hlt Eins hoch) a Tabelle 6.2: C++ news
    • 46 KAPITEL 6 EIN- UND AUSGABE - IIAlle benutzten fstream Methoden finden sie in Tab. 6.4.6.2.5 Einschub: Erstes Arbeiten mit MS VC++Wir haben den Editor von MS VC++ ja schon mehrfach benutzt, da die Syntax ¨des Quelltextes sehr sch¨n angezeigt wird (Abb. 6.3). Uberhaupt ist MS VC++ oein sehr sch¨nes Entwicklungssystem f¨ r Programmentwicklung ... Wir f¨ hren o u u ¨die Ubung E6.2.4 jetzt mal mit MS VC++ aus. Abbildung 6.3: Der MS VC++ EditorStandardm¨ßig werden folgende Einf¨rbungen benutzt f¨ r a a u • Keywords: Blau • Kommentare: Gr¨ n u • Normaler Quelltext: Schwarz • Includes: Rot
    • 6.2 ARBEITEN MIT FILE-STREAMS 47 • Zeichenketten: RotIch bin mir ziemlich sicher, dass man in einem gut versteckten MS VC++ Menu-punkt alles selber einstellen kann ...Highlighting of sytax ... ist nur eines der sehr n¨ tzliches features (langsam gleiten uwir in IT slang ab). Um MS VC++ richtig nutzen zu k¨nnen, m¨ ssen wir o uein sogenanntes Projekt anlegen (mal sehen, ob ihre Begeisterung danach nochanh¨lt). Die Schritte f¨ r die Projekterstellung finden sie in der Anlage (Abschn. a u12.4) ... Nachdem das Projekt angelegt ist, k¨nnen wir damit arbeiten. o ¨ Abbildung 6.4: Ubersetzen sie das Projekt mit F7 (build solution) Abbildung 6.5: Das Debug Verzeichnis
    • 48 KAPITEL 6 EIN- UND AUSGABE - IIMSVS legt allerhand Zeug’s an. Das executable finden sie im UnterverzeichnisDebug und kann nat¨ rlich mit einem Doppelklick gestartet werden. Wir starten udie Konsolenanwendung aus MSVS mit Ctrl-F5 (Abb. 6.6).Abbildung 6.6: Starten der Konsolenanwendung mit Ctrl-F5 oder Menu-Auswahl (Start without debugging) ¨Hier wartet schon die erste Uberraschung auf uns: pwd wird nicht erkannt undwir werden aufgefordert eine Zeit einzugeben (Abb. 6.7). Abbildung 6.7: Das Debug VerzeichnisWas ist passiert ? • pwd ist ein Linux-Befehl, den kennt der Windows-Compiler nicht. • time gibt es auch als DOS-Befehl, hat aber eine ganz andere Bedeutung: nicht Ausgabe der Zeit sondern Zeit ¨ndern. aWir sehen also, dass unser Quellcode von verschiedenen Compilern unterschied-lich interpretiert wird.
    • 6.3 FILE-STREAMS UND KLASSEN 49. Abbildung 6.8: Der Windows bereinigte QuelltextSie sehen ’Sch¨nheit’ hat auch ihren Preis ... dennoch die Funktionalit¨t der MS o aVC++ Entwicklungsumgebung, das muss man neidlos anerkennen, ist einfachKlasse.6.3 File-Streams und KlassenWir wollen eine Lesefunktion f¨ r die Klasse CStudent schreiben. Bevor wir udamit beginnen, m¨ ssen wir uns Gedanken uber eine geeignete Struktur f¨ r die u ¨ uDarstellung eines CStudent Datensatzes in einer Datei machen. Der Vorschlagf¨ r die Strukturierung von Datens¨tzen ist die Benutzung von Schl¨ sselw¨rtern u a u ozur Trennung von Datenbl¨cken, z.B. o#STUDENT $NAME_FIRST James $NAME_LAST Bond ...#STOPWir benutzen zwei verschiedene Symbole f¨ r Schl¨ sselw¨rter: u u o
    • 50 KAPITEL 6 EIN- UND AUSGABE - II • keyword # : zur Trennung von Datens¨tzen f¨ r eine Instanz von CStudent, a u • subkeyword $ : zur Identifizierung der einzelnen Daten f¨ r die CStudent u Instanz. • #STOP zeigt das Ende der Datenbasis an. (Eigentlich w¨re dies nicht a n¨tig, da das Dateiende auch mit dem Parameter eof (end-of-file) ab- o gefragt werden kann. Wir werden aber sehen, dass mit #STOP einiges einfacher zu programmieren ist.)Exercise E6.3: Implementierung der CStudent Lesefunktionios::pos_type CStudent::Read(ifstream& input_file){ //---------------------------------------------------------------------- string input_line; char buffer[256]; // MAX_LINE ios::pos_type position; //---------------------------------------------------------------------- while(true) { position = input_file.tellg(); input_file.getline(buffer,256); input_line = buffer; if(input_line.size()<1) // empty line continue; // Dealing with keywords if(input_line.find(’#’)!=string::npos) // keyword found return position; // Dealing with subkeywords if(input_line.find("$NAME_FIRST")!=string::npos) { input_file.getline(buffer,256); input_line = buffer; name_first = input_line; } if(input_line.find("$NAME_LAST")!=string::npos) { input_file >> name_last; } if(input_line.find("$subkeyword")!=string::npos) { input_file >> member; } } //---------------------------------------------------------------------- return position;}
    • 6.3 FILE-STREAMS UND KLASSEN 51Der Lesealgorithmus funktioniert wird folgt: Nach dem Auffinden eines Schl¨ ssel- uworts #STUDENT, wird in einer while Schleife nach subkeywords ($) gesucht,wenn gefunden, werden der CStudent Instanz die Werte aus der Eingabedateizugewiesen (also die Namen). Wenn das n¨chste Schl¨ sselwort (#STUDENT a uoder #STOP) gefunden wird, geht’s mit der vorletzten Position raus aus derFunktion. Die vorletzte position ist wichtig, damit die letzte Zeile sp¨ter noch- amal gelesen werden kann, um das Schl¨ sselwort auswerten zu k¨nnen ... u oDie Implementierung der main Funktion, in der die CStudent::Read() Funktionaufgerufen wird, ist im folgenden Block dargestellt.#include <iostream> // for using cout#include <fstream> // for using ifstream / ofstream#include <string> // for using string#include "student.h" // for using CStudentsusing namespace std; // for std functionsint main(){ //---------------------------------------------------------------- // File handling ifstream input_file; // ifstream instance input_file.open("data_set.txt"); if(!input_file.good()) // Check is file existing { cout << "! Error in STD::Read: file could not be opened" << endl; return 0; } input_file.seekg(0L,ios::beg); // Rewind file //---------------------------------------------------------------- CStudent* m_std = new CStudent(); // CStudent instance m_std->Read(input_file); //---------------------------------------------------------------- input_file.close(); return 0;}Die main Funktion besteht aus zwei Teilen, dem File-Handling und dem Aufrufder Lesefunktion. Beim File-Handling wird der stream aus der Datei data set.txtge¨ffnet, anschließend erfolgt der Test, ob das File erfolgreich ge¨ffnet werden o okonnte; wenn nicht, wir die main Funktion sofort beendet. ¨Was ist neu bei dieser Ubung.Wir benutzen den Referenz-Operator & (Kapitel 7) als Parameter der FunktionCStudent::Read(). Eine Referenz ist eigentlich nicht anderes als ein andererBezeichner (Alias) f¨ r eine bereits existierende Instanz eines Objekts. Es kann ualso mehrere solcher Referenzen geben und vor Benutzung einer Referenz mussdie Instanz des Objekts physikalisch (also speicherm¨ßig) vorhanden sein, sonst a’crashed’ unser Programm.
    • 52 KAPITEL 6 EIN- UND AUSGABE - II C++ Ding Was tut’s ifstream& input file eine Reference auf ein Objekt wird in Kapitel 7 ausf¨ hrlich abgehandelt u Tabelle 6.3: C++ news6.4 fstream MethodenDie bisher benutzten fstream Methoden sind in der Tab. 6.4 zusammengestellt. Methode Funktion open() o ¨ffnet die Datei good() ¨ tested erfolgreiche Offnung der Datei seekg(pos,ios::beg) geht zur Position pos in der Datei seekg(0L,ios::beg) spoolt zum Dateianfang zur¨ ck u tellg() merkt sich die aktuelle Position im stream getline(buffer,256) holt eine Zeile der L¨nge 256 (Zeichen) aus dem stream a und kopiert diese in buffer close() schließt Datei >> Eingabeoperator f¨ r Dateien u << Ausgabeoperator f¨ r Dateien u Tabelle 6.4: fstream MethodenDie string Auswertung spielt bei der Lesefunktion eine wichtige Rolle, daher ha-ben wir uns wir uns im vorangegangenen Kapitel mit der string Klasse besch¨ftigt. a
    • 6.5 TESTFRAGEN 536.5 Testfragen 1. Was ist die Basis-Klasse f¨ r alle Ein- und Ausgaben in C++ ? u 2. Was sind die C++ Klassen f¨ r das Lesen und Schreiben von Dateien ? u 3. Welchen Include ben¨tigen wir f¨ r das Arbeiten mit I/O File-Klassen ? o u 4. Was sind die Standard-Flags f¨ r File-Streams (Lesen und Schreiben) ? u 5. Mit welchem Flag k¨nnen wir zu schreibende Daten an eine existierende o Datei anh¨ngen ? a 6. Was ist der Unterschied zwischen ASCII- und Bin¨r-Formaten ? a 7. Mit welchem Flag k¨nnen wir Daten in einem Bin¨r-Format schreiben ? o a Mit welcher Anweisung wird ein File ge¨ffnet ? Mit welcher Anweisung o wird ein File geschlossen ? 8. Was bewirken die Stream-Operatoren << und >> ? 9. Wie k¨nnen wir mit Dateinamen in unserem Hauptprogramm main(...) o arbeiten ? 10. Welche Anweisung ben¨tigen wir f¨ r die Erzeugung einer Instanz f¨ r einen o u u Eingabe-Strom ? 11. Welche Anweisung ben¨tigen wir f¨ r die Erzeugung einer Instanz f¨ r einen o u u Ausgabe-Strom ? 12. F¨ r die Erstellung einer Datenbank ist es wichtig einzelnen Datens¨tze zu u a trennen. Wie k¨nnen wir soetwas in der Datenbank-Datei bewerkstelligen o ? 13. Ist es wichtig das Ende einer Datenbank-Datei, z.B. mit einem Schl¨ ssel- u wort #STOP, zu markieren ? o u ¨ 14. Mit welcher Abfrage k¨nne wir pr¨ fen, ob die Offnung einer Datei erfolg- reich war ? 15. Mit welcher Anweisung k¨nnen wir die aktuell gelesene Position in einer o ge¨ffneten Datei abfragen ? o 16. Mit welcher Anweisung k¨nnen wir zu einer bestimmten Position in einer o ge¨ffneten Datei springen ? o 17. Mit welcher Anweisung k¨nnen wir eine komplette Zeile aus ge¨ffneten o o Datei auslesen ?
    • Kapitel 7Referenzen und ZeigerReferenzen und Zeiger (pointer), d.h. die Symbole & und * sind uns bereitsmehrfach begegnet, z.B. in der Parameterliste der main() Funktion ... Generellk¨nnen Zeiger und Referenzen als einfache Variable, Parameter oder R¨ ckgabe- o uwert (return) einer Funktion auftauchen. ¨In der Ubung E6.3 haben wir bereits mit Referenzen gearbeitet und festgestellt,dass Referenzen eigentlich nichts anderes als andere Bezeichner (Alias) f¨ r eine ubereits existierende Instanz eines Objekts sind. Es kann also mehrere solcherReferenzen geben. Bei der Definition eines Zeigers wird also kein neuer Spei-cher reserviert. Die Instanz des Objekts muss physikalisch (also speicherm¨ßig) anat¨ rlich vorhanden sein, sonst ’verabschiedet’ sich unser Programm gleich wie- uder. x &ref_x x Referenz auf das Objekt y Objekt im Speicher Abbildung 7.1: Referenzen auf Objekte 54
    • 7.1 REFERENZEN 557.1 Referenzen7.1.1 Das Call-by-reference Prinzip - Referenzen als Pa- rameterDef: Eine Referenz ist nichts anderes als ein anderer Name (Alias) f¨ r ein bereits uexistierendes Objekt. Bei der Definition einer Referenz wird also kein neuerSpeicherplatz f¨ r das Objekt belegt (außer nat¨ rlich die 4 Byte f¨ r die Referenz u u uselbst).Die Abb 7.2 soll das Konzept des Referenzierens noch einmal verdeutlichen. • x ist die Instanz eines Datentyps T • &ref x ist eine Referenz (Verweis) auf x ¨In der ersten Ubung sehen die Definition von Referenzen und Zeigern im Quell-text¨Ubung: E7.1.1double x = 1.23456789;double* ptr_x;double& ref_x = x; // initialisation is needed ¨Die Bildschirmausgabe der ersten Ubung zeigt Folgendes: Abbildung 7.2: Referenzen auf ObjekteEine Referenz (ref x) muss bei der Definition initialisiert werden (mit x), sonstbekommen sie eine Fehlermeldung beim Kompilieren.Der Referenztyp-Parameter (&) ist ein Aliasname f¨ r das ’richtige’ Argument. uBeim Aufruf der Funktion wird der Referenz-Parameter mit dem Objekt initia-lisiert. Die Funktion arbeitet also direkt mit dem von außen ubergebenen Argu- ¨ ¨ment. Das ’Call-by-reference’ Prinzip ist sozusagen eine Ubergabe-von-Außen.Wir schauen uns dies mal an bei der CStudent-Lesefunktion aus der letztenVorlesung.¨Ubung: E7.1.1
    • 56 KAPITEL 7 REFERENZEN UND ZEIGERDefinition: CStudent::Read(ifstream& ref_input_file)Aufruf: ifstream input_file; CStudent* m_std = new CStudent(); // CStudent instance m_std->Read(input_file);Was passiert ? Beim Aufruf der Lese-Funktion Read wird die Adresse des ifstreamObjekts (input file) an die Funktion ubergeben. Das heisst die Lese-Funktion ¨arbeitet intern mit dem ’richtigen’ Objekt. ’Call-by-reference’ Prinzip erm¨glicht oes also der Funktion einen Zugriff auf Daten des Aufrufers.Beim sogenannten ’Call-by-value’ Prinzip k¨nnen Funktions-Argumente inner- ohalb der Funktion nicht ge¨ndert werden. a7.1.2 Referenzen als Ruckgabe-Wert ¨Referenzen auf Objekte k¨nnen auch R¨ ckgabe-Werte von Funktionen sein. o u¨Ubung: E7.1.2 (aus [5])Definition: string& message() { static string m_str("Vorsicht Speicher-Falle"); return m_str; }Aufruf:!!! Das Objekt muss nach dem Verlassen der Funktion noch existieren ¨Was ist neu bei dieser Ubung. C++ Ding Was tut’s static Speicherklasse: der Speicher f¨ r das Objekt bleibt w¨hrend u a der gesamten Programmausf¨ hrung bestehen, u wird in Kapitel 7.3 ausf¨ hrlich abgehandelt. u Tabelle 7.1: C++ news7.2 ZeigerZeiger sind eine der Grundideen moderner Programmiersprachen. Dabei arbei-tet man nicht direkt mit den Daten-Bl¨cken im Speicher sondern mit deren oAdressen. Dies macht insbesondere Sinn, wenn es um große Daten-Objekte geht
    • 7.2 ZEIGER 57oder bei Objekten, die erst zur Laufzeit angelegt werden (z.B. Vektoren, Li-sten, Strings). Das Klassen-Prinzip unterst¨ tzt die Zeigertechnik optimal, da udie Klasse ihre Daten ja selber verwaltet (siehe Klassenkonstruktur) Der Zeiger(pointer) auf ein Objekt repr¨sentiert dessen Adresse und Daten-Typ. a7.2.1 Definition von Zeigern ¨Die nachfolgende Ubung zeigt, wie wir Zeiger definieren und mit ihnen arbeitenk¨nnen. F¨ r den Zugriff auf Zeiger gibt es den sogenannten Verweisoperator ’*’. o u¨Ubung: E7.2 (aus [5])int main(){ int i, *ptr_i; // Definitionen i = 100; // Zuweisung ptr_i = &i; // Dem Zeiger wird die Adresse der integer Variable i zugewiesen *ptr_i += 1; // Die integer Variable i wird um Eins erh¨ht (i += 1;) o}⇒Geben sie Werte und Adressen der Integer-Variable i und den Zeiger auf i(i ptr) aus.Unabh¨ngig vom Daten-Typ ist der ben¨tigte Speicher f¨ r eine Zeigervariable a o uimmer gleich groß - der zur Speicherung ben¨tigte Platz f¨ r die Adresse des o uObjekts (4 Byte auf einer 32-Bit-Rechner-Architektur, siehe auch Abb. 7.2). ¨Was ist neu bei dieser Ubung. C++ Ding Was tut’s *ptr Verweisoperator (un¨r: ein Operand) a i*i Multiplikations-Operator (bi¨r: zwei Operanden) a Tabelle 7.2: C++ news: Operatoren7.2.2 NULL ZeigerWir haben gesehen, dass Referenzen auf Daten-Objekte zwingenderweise in-itialisiert werden m¨ ssen (sonst streikt der Kompiler). Zeiger m¨ ssen eigentlich u unicht initialisiert werden, ihnen wird bei der Definition eine ’vern¨ nftige’ Adres- use zu gewiesen. Dies bedeutet noch lange nicht, dass sich hinter dieser Adresseetwas Vern¨ nftiges verbirgt. Daher ist es ratsam, auch Zeiger zu initialisieren, uum Nachfragen zu k¨nnen, ob sie tats¨chlich auf existierende Objekte zeigen. o aZum Initialisieren von Pointern gibt es den NULL-Zeiger.
    • 58 KAPITEL 7 REFERENZEN UND ZEIGERdouble* ptr_x = NULL;ptr_x = &x;if(!ptr_x) cout << "Warning: ptr_x does not have a meaningful adress";Der linke Operand der Operators = muss immer auf eine ’sinnvolle’ Speicher-stelle verweisen. Dieser wird daher auch als so genannter L-Wert (L(eft) value)bezeichnet. Wenn eine Fehlermeldung ’wrong L-value’ erscheint, wissen sie, dasskeine ’sinnvolle’ Adresse vergeben wurde, dies spricht wiederum f¨ r eine Initia- ulisierung von Zeigern mit Zero-Pointer.7.2.3 Zeiger als ParameterDer Verweisoperator ist uns unl¨ngst schon mal begegnet bei der erweiterten amain() Funktion mit Eingabeparametern: int main(int argc, char* argv[])7.3 Zeiger und ArraysWie bereits gesagt, die Verzeigerungs-Technik ist eine der Besonderheiten vonobjekt-orientierten Sprachen, wie z.B. von C++. Mit solchen Pointern k¨nnen owir auch gr¨ßere Daten-Objekte wie Vektoren verwalten. Die zentrale Idee ist: oWenn Startpunkt (id Adresse) und L¨nge des Vektors bekannt sind, wissen wir aeigentlich alles und k¨nnen auf alle Vektor-Daten zugreifen. o7.3.1 Statische ObjekteBei der Einf¨ hrung der String-Klasse hatten wir bereits mit Zeichenketten zu utun. Aus der Sicht des Speichers ist eine Zeichenkette ein Vektor der eine be-stimmte Anzahl von Zeichen enth¨lt. Vektoren k¨nnen nat¨ rlich f¨r (fast) alle a o u uDatentypen definiert werden. Im n¨chsten Kapitel (8) besch¨ftigen wir uns mit a asogenannten Containern, damit k¨nnen z.B. Vektoren, Listen etc. f¨ r ganze o uKlassen generiert werden.char Zeichenkette[80];int iVektor[50];double dVektor[50];7.3.2 Dynamische ObjekteBisher haben wir uns fast ausschließlich mit Datentypen besch¨ftigt, deren aSpeicherbedarf bereits w¨hrend der Kompilierung fest steht und reserviert wird a(bis auf Strings-Objekte). Es gibt aber auch die M¨glichkeit, den Speicherbe- odarf w¨hrend der Programmausf¨ hrung zu ¨ndern - dies geht mit dynamischen a u aDaten-Objekten. Die werden wir folgt deklariert.
    • 7.4 SUMMARY 59char* Zeichenkette;int* iVektor;double* dVektor;Nun m¨ ssen wir uns allerdings selber um die Speicherreservierung k¨ mmern. u u ¨Dies erfolgt mit dem new-Operator und wird in der n¨chsten Ubung gezeigt. aWir ahnen schon, wenn es etwas zum Vereinbaren von Speicher gibt, muss eswohl auch das Gegenst¨ ck - freigeben von Speicher - geben. Nat¨ rlich habe sie u uRecht. Dies erledigt der delete-Operator.double* dVektor;dVektor = new double[1000];delete [] dVektor;Die Anwendung beider Operatoren zum Speichermanagement sowie eine M¨glich- o ¨keit, den verbrauchten Speicher zu messen, werden in der folgenden Ubung ge-zeigt.¨Ubung: E7.3.2#include <iostream> // for using cout#include <malloc.h> // for using malloc_usable_sizeusing namespace std;int main(){ char* Zeichenkette; // Definitions long size_memory; // Auxiliary variable for memory size Zeichenkette = new char[1000]; // Memory allocation size_memory = malloc_usable_size(Zeichenkette); // calculation of memomry delete [] Zeichenkette; // Memory release return 0;}HomeWork: HW7.3.2Schreiben sie ein kleines Programm, mit der sie den ben¨tigten Speicher ermit- oteln k¨nnen und pr¨ fen sie, ob die Freigabe des Speichers funktioniert hat. o uZeiger k¨nnen auch verschachtelt werden: Zeiger auf Zeiger ... Damit lassen sich omehrdimensionale Datenstrukturen schaffen, z.B. Matrizen.7.4 SummaryDas Verstehen und Arbeiten mit Zeigern und Referenzen ist nicht ganz ein-fach und braucht eine ganze Zeit der praktischen Anwendung. Der *Operator
    • 60 KAPITEL 7 REFERENZEN UND ZEIGER **matrix *matrix[0] *matrix[1] *matrix[2] *matrix[1][0] *matrix[1][1] *matrix[1][2] Abbildung 7.3: Die Definition einer Matrix mittels Pointerkann beispielsweise als Zeiger auf etwas und gleichzeitig f¨ r dynamische Vek- utoren benutzt werden. Dies scheint zun¨chst absolut verwirrend zu sein, beim a ¨genaueren Uberlegen aber: * ist lediglich die Startadresse f¨ r den Vektor. Mer- uken sie sich erst einmal nur, dass es geschickter (und schneller) ist, nicht mitden Daten-Objekten direkt sondern mit Verweisen darauf (also deren Adres-sen) zu arbeiten. Die nachfolgende Tabelle und Abbildung sollen das Thema’Referenzen und Zeiger’ noch einmal illustrieren. Syntax Bedeutung double x Definition einer doppelt-genauen Gleitkommazahl (Speicherbedarf 8 Byte) double* ptr Zeiger auf eine doppelt-genauen Gleitkommazahl (Speicherbedarf 4 Byte) double& ref Referenz auf eine doppelt-genaue Gleitkommazahl (Speicherbedarf 4 Byte) double* dVektor Zeiger auf einen Gleitkommazahl-Vektor Tabelle 7.3: Zeiger und Referenzen ptr_x x &x x &ptr_x ptr_x *ptr_x Adresse von ptr_x Adresse von x Wert von x Wert von ptr_x Abbildung 7.4: Referenzen und Zeiger (nach [5])
    • 7.5 TESTFRAGEN 617.5 Testfragen 1. Was ist &x ? (x ist ein beliebiger Datenobjekt T, z.B. eine Gleitkomma- zahl: double x) 2. Was ist eine Referenz &ref? 3. Was bedeutet die Anweisung: &ref = x? 4. Erkl¨ren sie kurz (mit eigenen Worten) das Zeiger-Konzept in C++? a 5. Was bewirkt der NULL Zeiger, d.h. *ptr = NULL ? 6. Was bedeutet die Anweisung: ptr = x? 7. M¨ ssen Referenzen (&) und Zeiger (*) auf Daten-Objekte initialisiert wer- u den ? 8. Was bewirkt die Definition long l[1000] speichertechnisch ? 9. Wie groß ist der Speicherbedarf des statischen Datenobjekts long l[1000] ? 10. Wie groß ist der Speicherbedarf des dynamische Datenobjekts long* ptr l = new long[1000] ? 11. Woher kommt der Unterschied (4 Byte auf einem 32Bit Rechner) im Speicherbedarf zwischen statischen und dynamischen Datenobjekten. 12. Zusatzfrage: Was bedeutet die Definition **ptrptr (Zeiger auf Zeiger), was f¨ r ein Datenkonstrukt entsteht ? u
    • Kapitel 8ContainerWir haben bereits mit der String-Klasse gesehen, dass C++ neben der Ba-sisfunktionalit¨t einer Programmiersprache auch sehr n¨ tzliche Erweiterungen, a uwie das Arbeiten mit Zeichenketten, anbietet. Diese Erweiterungen geh¨ren ozum Standard von C++, geh¨ren also zum ’Lieferumfang’ des Compilers dazu ound heißen daher auch Standard-Klassen. Diese Klassen bilden die sogenannteStandard-Bibliothek (STL - STandard Library).In diesem Kapitel besch¨ftigen wir uns mit sogenannten Containern mit de- anen Daten organisiert, gespeichert und verwaltet werden k¨nnen, z.B. Listen ound Vektoren. In der Abb. 8.1 sind die wichtigsten Elemente der Containerdargestellt. Der Begriff Container soll verdeutlichen, dass Objekte des gleichenTyps z.B. in einer Liste gespeichert werden. Und wie immer bei Klassen, werdennat¨ rlich auch die Methoden f¨ r den Zugriff oder die Bearbeitung von diesen u uObjekten bereitgestellt. Die Speicherverwaltung f¨ r Container-Elemente erfolgt udynamisch zur Laufzeit (siehe Kapitel Speicherverwaltung). Die Abb. 8.1 zeigtauch, welche verschiedenen Typen von Containern es gibt:Sequentielle Container: sind z.B. Vektoren, Listen, Queues und Stacks. Vek- toren sind Felder (arrays) in denen die einzelnen Elemente nacheinander angeordnet sind. Bei einer Liste kennt jedes Element nur seine Nach- barn (Vorg¨nger- und Nachfolgeelement). Queues (wir kennen dies von a Druckern) sind Warteschlangen, die nach dem FIFO-Prinzip (first in, first out) funktionieren. Das heißt, dass zuerst eingef¨ gte Element wird auch u zuerst verarbeitet (z.B. Druckjobs). Stacks sind sogenannte Kellerstapel, die nach dem LIFO-Prinzip (last in, first out) funktionieren. Das bedeutet, das zuletzt eingef¨ gte Element wird zuerst verarbeitet. uAssoziative Container: sind z.B. Maps (Karten) und Bitsets. Die Elemen- te sind nicht wie bei sequentiellen Container linear angeordnet sondern in bestimmtem Strukturen (z.B. Baumstrukturen). Dies erm¨glicht einen o besonders schnellen Datenzugriff, der uber eine Verschl¨ sselung erfolgt. ¨ u 62
    • 8.1 SEQUENTIELLE CONTAINER 63 Container sequential associative Container Container Vectors Stacks Queues Sets Maps Bitsets Abbildung 8.1: C++ Container (Bildquellen: www.prachensky.com)Die Besonderheit der C++ Container ist die dynamische Speicherverwaltung.Das heisst, Einf¨ gen und Entfernen von Container-Elementen ist sehr einfach, uwir brauchen uns nicht selbst um das Speichermanagement zu k¨ mmern. Dies uubernehmen die Konstruktoren und Destruktoren (siehe Abschnitt 4.4) der je-¨weiligen Container-Klasse.8.1 Sequentielle ContainerEin weiterer Grund f¨ r die Bereitstellung von Containern ist, dass die Elemente ugemeinsame Datentypen und Methoden haben. Der Datentyp T eines Containersist nat¨ rlich eine (beliebige) Klasse. Die Tab. 8.1 listet die Klassentemplates f¨ r u ueinige sequentielle Container sowie die ben¨tigen Include-Files auf. oEin Klassentemplate ist nichts weiter als eine formale Beschreibung der Syntax.
    • 64 KAPITEL 8 CONTAINER Klassen-Template Include-Files vector<T,Allocator> <vector> list<T,Allocator> <list> stack<T,Container> <stack> queue<T,Container> <queue> Tabelle 8.1: Klassentemplates f¨ r sequentielle Container u • vector: Schl¨ sselwort u • < ... >: Parameterliste • T: erster Parameter, Datentyp des Vektors • Allocator: zweiter Parameter, Speichermodell des VektorsDie Methoden sequentieller Container sind sehr einfach, intuitiv zu bedienenund sie sind gleich f¨ r Vektoren, Listen etc. Ein Auswahl der wichtigsten ge- umeinsamen Methoden finden sie in der nachfolgenden Tabelle. Methode Bedeutung size() Anzahl der Elemente, L¨nge de Containers a push back(T) Einf¨ gen eines Elements am Ende u pop back() L¨schen des letzten Elements o insert(p,T) Einf¨ gen eines Elements vor p u erase(p) L¨schen des p-Elements (an der Stelle p) o clear() L¨scht alle Elemente o resize(n) ¨ Andern der Containerl¨nge a Tabelle 8.2: Methoden f¨ r sequentielle Container u8.2 VectorsThe standard vector is a template defined in namespace std and presented in<vector>. The vector container is introduced in stages: member types, iterators,element access, constructors, list operations etc. The structure of a vector isillustrated in Fig. 8.2. Abbildung 8.2: Structure of vectorsFollowing lines are necessary in order to use the vector container in your sourcescode.
    • 8.2 VECTORS 65#include <vector>using namespace std;Types: Very different types can be used in vectors. A vector e.g. of integers canbe declared in this way.// Declaration and construction vector<int> v;Constructors: With the above source code a vector of integer types is constructedas well.Stack operators: The functions push back and pop back treat the vector as astack by adding and removing elements from its end.// Input elements to vector for(i=0;i<9;i++) { v.push_back(i+1); }Iterators: Iterators can be used to navigate containers without the programmerhaving to know the actual type to identify the elements, e.g. for inserting anddeleting elements. A few number of key functions allow to step through theelements, such as begin() pointing to first element and end() pointing to theone-past-last element. An example of a loop through all vector elements usingthe iterator is given below.// Navigating vector elements for(vector<int>::iterator it=v.begin(); it!=v.end(); ++it) { cout << *it << ’n’; }Vector elements can be addressed directly by element number. Fast data accessis an advantage of vectors. Abbildung 8.3: Access to vector elementsIn contrast, vectors are not as flexible as lists. Deleting and adding of elementswithin the vector is complicated (Fig. 8.4).
    • 66 KAPITEL 8 CONTAINER Abbildung 8.4: Deleting elementsProgramming exercises8.2.1 Defining vectorsIn the first exercise we just define a vector and insert some elements into it inorder to show the concept.Exercise 8.2.1#include <iostream> // for using cout#include <vector> // for using vectorsusing namespace std; // for std functionsvoid main(){ //------------------------------------------------------- cout << "E81 - Working with vectors" << endl; //------------------------------------------------------- vector<int>my_vector; // Declaration of vector my_vector.push_back(1); // Inserting an element to vector my_vector.push_back(3); my_vector.push_back(5); for(int i=0;i<(int)my_vector.size();i++) { cout << my_vector[i] << endl; // Access to vector elements } //-------------------------------------------------------}8.2.2 Vectors and data base ¨In der n¨chsten Ubung werden einige Dinge, die wir bisher gelernt haben, zu- asammenbringen. Sie werden sehen, dass ’gut’ programmierte Dinge einfach ’zu-sammengebaut’ werden k¨nnen: Objekte (Kapitel 4), IO-Methoden (Kapitel 6), oStringverarbeitung (Kapitel 5).
    • 8.2 VECTORS 67Exercise 8.2.2#include <iostream> // for using cout#include <fstream> // for using ifstream / ofstream#include <string> // for using string#include <vector> // for using vectors#include "student.h" // for using CStudentsusing namespace std; // for std functions#define MAX_ZEILE 256bool STDRead(ifstream&);int main(){ //---------------------------------------------------------------- cout << "E82: an object-oriented DB read function" << endl; //---------------------------------------------------------------- // 1 File handling ifstream input_file; // ifstream instance input_file.open("data_base.txt"); if(!input_file.good()) // Check is file existing { cout << "! Error: input file could not be opened" << endl; return 0; } //---------------------------------------------------------------- // 2 Read data base STDRead(input_file); //---------------------------------------------------------------- return 0;}Unser Programm besteht aus drei gekapselten Teilen: • main(): Das Hauptprogramm: die Steuerzentrale, hier wir i.W. das Da- teimanagement erledigt. • STDRead(ifstream&): Die ubergeordnete Lesefunktion f¨ r die komplet- ¨ u te Datenbank, hier befindet sich eigentlich nur eine Schleife, welche die Objekt-Lesefunktion aufruft, solange Daten in der Datei vorhanden sind. • CStudent::Read(ifstream): Die Objekt-Lesefunktion, die liest die ei- gentlichen Daten f¨ r jeden Datensatz aus der Datenbankdatei. u ¨Der einzige Ubergabeparameter ist die Datenbank-Datei: std file.
    • 68 KAPITEL 8 CONTAINERExercise 8.2.2 continued/**************************************************************************STDLib-Method:Task: Reading all STD objects06/2009 OK Implementation**************************************************************************/bool STDRead(ifstream& std_file){ //-1-------------------------------------------------------------------- char line[MAX_ZEILE]; string line_string; ios::pos_type position; vector<CStudent*>std_vector; CStudent* m_std = NULL; //----------------------------------------------------------------------//OK STDDelete(); //-2-------------------------------------------------------------------- // rewind the file std_file.seekg(0,ios::beg); //-3-------------------------------------------------------------------- // OBJ reading, keyword loop cout << "STDRead" << endl; while (!std_file.eof()) { std_file.getline(line,MAX_ZEILE); line_string = line; if(line_string.find("#STOP")!=string::npos) break; if(line_string.find("#STUDENT")!=string::npos) { m_std = new CStudent(); position = m_std->Read(std_file); // from E63 std_vector.push_back(m_std); std_file.seekg(position,ios::beg); } } // eof //---------------------------------------------------------------------- cout << "Number of data sets: " << std_vector.size() << endl; return true;}8.2.3 Updating your data base entryHomework 8.2.3a: Please update your data base entries and send it by mail tome (olaf.kolditz@ufz.de).Homework 8.2.3b: Please write a print function for the CStudent class.
    • 8.3 LISTS 698.3 ListsA list is a sequence optimized for insertion and deletion of elements. They allowa very flexible organization of elements. But the price for flexibility is a relativelyslow access to data.List provides bidirectional iterators (Fig. 8.3). This implies that a STL list willtypically be implemented using some form of a doubly-linked list. Abbildung 8.5: Structure of listsFollowing lines are necessary in order to use the list container in your sourcescode.#include <list>using namespace std;Types: All data types are possible for lists, e.g. a class.// Declarationlist<CStudent*> std_list;list<int> int_list;Constructors: With the above source code a list for class instances is constructedas well.Stack operators: Lists provide same typical member functions as for vectors.// Insert list elements at endCStudent* m_std;my_list.push_back(m_std);Iterators: Again iterators can be used to navigate lists. We show an example fordeleting a specific element from the list. Identification of the list element is byname (Fig. 8.6). Abbildung 8.6: Deleting list elementsThe following exercise shows how conveniently we can deal with lists, i.e. inorder to sort, reverse, merge, and unify lists. The unifying function removes
    • 70 KAPITEL 8 CONTAINERmultiple entries from lists, which is a very nice tool in order to clean a database.Exercise 8.3#include <iostream> // for using cout#include <list> // for using listsusing namespace std; // for std functionstypedef list<int>INTLIST;void display(list<int>);int main(){ int i; list<int>list1; INTLIST list2; // Filling the list with random numbers for(i=0;i<4;i++) { list1.push_back(rand()%10); list2.push_back(rand()%10); } display(list1); // Display the list display(list2); // Putting first element to the end as well list1.push_back(list1.front()); list1.reverse(); // Reverse list list1.sort(); // Sort list list1.merge(list2); // Merge two lists list1.sort(); // Remove multiple entries #1 list1.unique(); // Remove multiple entries #2 return 0;}void display(list<int>my_list){ int i; list<int>::const_iterator iterator; iterator = my_list.begin(); while(iterator != my_list.end()) { i = *iterator; cout << i << endl; ++iterator; }}The concept of the data base read function is illustrated in Fig. 8.7.
    • 8.4 TESTFRAGEN 71 main() Files STDRead(ifstream&) STD::Read() Abbildung 8.7: Data base read conceptThe last exercise shows how we can delete entries from the students data base(i.e. people we don’t like)// Deleting list elementsCStudent* m_std = NULL;list<CStudent*>::const_iterator p = std_list.begin();while(p!=std_list.end()){ m_std = *p; if(m_std->GetStudentName()=="James Bond") { my_list.remove(*p); break; } ++p;}// Deleting repeated entriesstd_list.unique();8.4 Testfragen 1. Was sind C++ Container ? 2. Welche Typen von C++ Containern kennen sie ? 3. Worin besteht der Unterschied zwischen sequentiellen und assoziativen Containern ? 4. Welche sequentiellen Container kennen sie ? 5. Erkl¨ren sie die Syntax des Vektor-Containers: vector<int>my vector . a 6. Was ist der Unterschied zwischen Vektoren und Listen ? 7. Was sind die Gemeinsamkeiten von Vektoren und Listen ? 8. Welcher Include ist notwendig f¨ r das Arbeiten mit Vektoren ? u 9. Welcher Include ist notwendig f¨ r das Arbeiten mit Listen ? u
    • 72 KAPITEL 8 CONTAINER 10. Ben¨tigen wir den Zusatz (Namensraum) using namespace std, wenn ja o warum ? 11. Mit welcher Instruktion k¨nnen Elemente in Vektoren und Listen einf¨ gen o u ? 12. Wo werden sequentielle Container-Elemente mit der Instruktion push back(T) eingef¨ gt ? u 13. Mit welcher Anweisung k¨nnen wir die L¨nge von sequentiellen Container- o a Elementen bestimmen ? 14. Mit welcher Anweisung k¨nnen wir einen Vektor platt machen (d.h. alle o Elemente l¨schen) ? o 15. Wie k¨nnen wir auf ein Vektor-Element, sagen wir das 17te Element des o Vektors vector<int>my vector, direkt zugreifen ? 16. Quellcode verstehen: Erkl¨ren sie die Struktur (1,2,3) der DB-Lese-Funktion a ¨ STDRead(ifstream& std file) in der Ubung 8.2.2. Beginnen sie mit der Pa- rameterliste. 17. Wie k¨nnen wir unsere Studenten-Klasse CStudent in die DB-Anwendung o ¨ (Ubung 8.2.1) einbinden ? u a ¨ 18. Was ist eigentliche Lesefunktion f¨ r unsere Studenten-Datens¨tze (Ubung 8.2.2) ? 19. Mit welchem Befehl k¨nnen wir die Reihenfolge von Listen-Elementen o umkehren ? 20. K¨nnen wir Listen-Elemente sortieren, wenn ja wie, mit welcher Instruk- o tion ? 21. Mit welchem Befehl k¨nnen wir mehrere Listen zusammenf¨ hren ? o u 22. K¨nnen wir doppelte Elemente aus einer Liste entfernen sortieren, wenn o ja wie, mit welcher Instruktion ? 23. Was ist ein Iterator ? 24. Quellcode verstehen: Erkl¨ren sie die Funktion void display(list<int>my list) a ¨ der Ubung 8.3. Beginnen sie mit der Parameterliste. 25. Wie k¨nnen wir Elemente aus einer Liste entfernen ? o
    • Kapitel 9Andere SprachelementeWir haben das Ende der C++ Grundvorlesung erreicht (hoffentlich ein Grundzur Freude). Das Ziel der Vorlesung ’Hydroinformatik’ ist allerdings bei Weitemnoch nicht erreicht. Sie erinnern sich, wir wollen eine Dialog-gef¨hrte Datenbank- uAnwendung (Fig. 4) mit C++ entwickeln. Sie werden sehen, dass wir fast al-le Bausteine beisammen haben (außer die Grafik-Programmierung mit VisualC++) und die Realisierung unser Applikation (nach der langen Vorbereitung)dann sehr schnell geht.Bevor wir zum graphischen (Visual) C++ kommen, wollen wir Sprachelemen-te (C++ news), die wir zuvor schon benutzt haben, aber noch nicht explizitbesprochen haben, hier kurz einf¨ hren. u9.1 KontrollstrukturenBei Kontrollstrukturen handelt es sich um Sprachelemente f¨ r bedingte Anwei- usungen und Schleifen mit Z¨hlern und Bedingungen. a Control Bedeutung if-else Anweisungen mit Bedingungen switch-case Fallunterscheidungen for Schleifen mit Z¨hlern a while Schleifen mit Bedingungen Tabelle 9.1: KontrollstrukturenVerschachtelungen von Kontrollstrukturen sind nat¨ rlich m¨glich. u o 73
    • 74 KAPITEL 9 ANDERE SPRACHELEMENTE9.1.1 if-elseEs geht um die Ausf¨ hrung von Anweisungen und Alternativen unter bestimm- uten Bedingungen. Ausf¨ hrung einer Anweisung unter einer Bedingung (siehe, u ¨z.B. Ubung 8.2.2):if(logische Bedingung){...} // Ausf¨hrung, wenn Bedingung erf¨llt ist u uAusf¨ hrung einer Anweisung unter einer Bedingung mit Alternative (else) (sie- u ¨he, z.B. Ubung 8.2.2):if(logische Bedingung){...} // Ausf¨hrung, wenn Bedingung erf¨llt ist u uelse{...} // Ausf¨hrung, wenn Bedingung nicht erf¨llt ist u u9.1.2 switch-caseDie Kontrollstruktur switch-case bietet die M¨glichkeit von Fallunterscheidun- ogen durch Ausdr¨ cke (z.B. Aufz¨hlungen durch Zahlen). Der Schalter switch u aspringt entsprechend dem Zahlenausdruck in einen Fall case.switch(Ausdruck){ case 0: // wenn Ausdruck == 0 ... // Anweisungen break; // Verlassen default: // wenn kein Ausdruck zutrifft}Es gibt eine weitere Variante, wo der Ausdruck ein Zeichen sein kann.switch(Ausdruck){ case ’A’: // wenn Ausdruck == A ... // Anweisung break; // Verlassen}Eine weitere M¨glichkeit diese Kontrollstruktur elegant einzusetzen ist die Be- onutzung von enum - einem Konstrukt f¨ r eigene Z¨hler. u aenum Wochentag {Montag,Dienstag,Mittwoch,Donnerstag,Freitag,Samstag,Sonntag}Die einzelnen Wochentage bekommen dann aufsteigende Werte (von 0 begin-nend) zugewiesen. Dann k¨nnen wir unsere Fallunterscheidung (z.B. f¨ r das o uMensa-Men¨ ) wie folgt schreiben: u
    • 9.1 KONTROLLSTRUKTUREN 75switch(Wochentag){ case Montag: // wenn Wochentag == 0 case Dienstag: // wenn Wochentag == 1 ... case Sonntag: // wenn Wochentag == 6}9.1.3 forDie for Schleife ist eine Schleife mit einem Z¨hler. afor(int i=0;i<stop;i++){... // Anweisungen}Die Anweisungen im Funktionsrumpf {...} werden solange ausgef¨ hrt, bis der uZ¨hler den Wert stop erreicht (das heißt, f¨ r den Wert stop wird die Schleife a unicht mehr ausgef¨ hrt). Bei jedem Schleifendurchlauf wird der Z¨hler i um Eins u a(i++) hochgez¨hlt. Ich habe gerade mal nachgesehen. In unserem Programm- asystem OpenGeoSys wird die for-Schleife uber 4000 mal verwendet! Wir haben ¨ ¨sie z.B. in der Ubung 8.2.1 zum Generieren von Vektor-Elementen benutzt.9.1.4 whileDie while Schleife ist eine Endlos-Schleife mit einer Bedingung.while(Bedingung){... // Anweisungen}Die Anweisungen im Funktionsrumpf {...} werden ausgef¨ hrt, solange die Be- udingung erf¨ llt (das heißt, der numerische Wert Bedingung muss gr¨ßer als 0 u osein). Um aus der Schleife herauszukommen, muss also der Wert der Bedingungge¨ndert werden - oder ’hart’ abgebrochen werden (siehe n¨chster Abschn. 9.1.5) a aIn unserem Programmsystem OpenGeoSys wird die while-Schleife fast 500 mal ¨verwendet! Wir haben sie f¨ r unsere Lesefunktion (Ubung 8.2.1) und beim Ite- u ¨rieren in Listen (Ubung 8.2.1) verwendet.9.1.5 continue, break, returnEs gibt mehrere M¨glichkeiten, um Kontrollstrukturen (vorzeitig) verlassen zu ok¨nnen. o
    • 76 KAPITEL 9 ANDERE SPRACHELEMENTE9.2 Gultigkeitsbereiche ¨F¨ r alles, was wir deklarieren, Funktionen, Klassen, Variablen gibt es G¨ ltig- u ukeitsbereiche. Wenn irgendwo etwas definieren, ist es also nicht uberall sicht- ¨bar. Wir hatten uns mit diesem Thema schon bei der Definition von ’privaten’Klassen-Elementen besch¨ftigt (Abschn. 4.6). Die Abb. ?? zeigt das Prinzip von alokalen und globalen G¨ ltigkeitsbereichen. Wir sollen immer versuchen soviel uwie m¨glich lokal zu definieren, das unterst¨ tzt die Daten-Kapselung in unse- o urem Programm. Klassen sind immer nur dort sichtbar, wo ihre Header-Dateieninkludiert worden sind.9.2.1 NamensbereicheSind uns auch schon mehrfach begegnet bei der Verwendung von Strings, Vekto-ren und Listen. Dabei wurde nach dem Includieren der entsprechenden Header-Dateien die Anweisung using namespace std benutzt. Strings, Vektoren undListen geh¨ren zum Namensraum der Standard-Bibliothek STL. o#include <strings>std::my_string("Beispiel ohne Namensbereich");using namespace std;my_string("Beispiel mit Namensbereich");Wir k¨nnen auch eigene Namensbereiche definieren. onamespace Meins{ // hier sind Funktionen des Namensbereichs class CStudent}using namespace Meins;Wozu ? Wenn sie ihren Programmcode mit einem anderen Entwickler zusam-menf¨ hren wollen und es gibt mehrere Klassen CStudent, dann k¨nnen sie sicher u oauf ihre Funktion zugreifen, wenn sie ihren Namensraum gesetzt haben.9.2.2 Compiler-Direktiven – #Alles was mit # anf¨ngt, versetzt den Kompiler in den Alarmzustand - es sind asogenannte Kompiler-Direktiven, das heißt beim Kompilieren werden gewisseWeichen gestellt.
    • ¨9.2 GULTIGKEITSBEREICHE 77 Direktive Wirkung #include Einf¨ gen einer Header-Datei u #define Definition einer Direktive #ifdef Wenn die Direktive gilt #ifndef Wenn sie nicht gilt #endif Ende der Direktive #define Definition eines Makros Tabelle 9.2: Compiler-Direktiven9.2.2.1 IncludesOhne Includes geht gar nichts, sie erinnern sich, selbst um einfache Bildschirm-ausgaben mit cout machen zu k¨nnen mussten wir Klasse iostream einf¨ gen. o uAn dieser Stelle nochmal zur Erinnerung. Es gibt Arten von Includes:<Header> Die eckigen Klammern bedeuten, es geht um einen System-Inklude. Es wird im Systemverzeichnis (dort wo C++ installiert ist) gesucht.”Header” Die G¨nsef¨ ßchen bedeuten, es geht um einen eigenen Inklude. Es a u wird lokalem Verzeichnis gesucht.Wenn der Programm-Code verzweigt ist, also eine komplexere Verzeichnisstruk-tur hat, m¨ ssen Pfade der Inklude-Dateien mit angegeben werden, sonst werden usie nicht gefunden. Keine Angst, in diesem Falle bekommen sie sofort eine ein-deutige Fehler-Meldung beim Versuch zu Kompilieren.9.2.2.2 Bedingte KompilationEine sehr n¨ tzliche Sache sind Direktiven f¨ r die Kompilation von Test-Versionen. u uGerade w¨hrend der Entwicklung m¨chte man neue Programmteile einfach an- a ound ausschalten k¨nnen. Dies geht mit der Kompiler-Direktive (KD) #ifdef. o#define TEST // Anschalten der Direktive TEST#ifdef TEST...#endifWenn die Kompiler-Direktive TEST an ist, wird der Programmtext von der Stel-le #ifdef bis #endif beim Kompilieren ubersetzt, ansonsten einfach ignoriert. ¨Kompiler-Direktiven sind immer aus, wenn sie nicht explizit eingeschaltet wer-den. Das Gegenst¨ ck von #ifdef ist #infdef, also wenn die Kompiler-Direktive uaus ist. Oft m¨ ssen Funktionen uberarbeitet werden. Mit Kompiler-Direktiven u ¨kann man sehr sch¨n eine neue Variante der Funktion entwickeln und die alte o
    • 78 KAPITEL 9 ANDERE SPRACHELEMENTEerstmal zu Vergleichszwecken beibehalten. Erst wenn alles richtig funktioniert,schmeißt man das alte Zeug weg.¨Ubung 9.2.2.2:#define NEW_VERSION // Anschalten der Direktive NEW_VERSION#ifdef NEW_VERSION... // wenn NEW_VERSION an ist#else... // wenn NEW_VERSION aus ist#endif ¨Ich empfehle ihnen, das mal in irgendeiner Ubung auszuprobieren. Wichtig:Denken sie immer an das #endif zum Ausschalten, sonst gilt die Kompiler-Direktive bis zum Ende des gesamten Programms.9.2.2.3 MakrosDie Kompiler-Direktive #define kann auch zur Definition sogenannter Makrosverwendet werden, z.B. f¨ r Konstanten, die man oft benutzt. Es geht aber auch uf¨ r einfache Funktionen oder sogar Print-Anweisungen. u#define PI 3.1416 // Definition der Zahl PI#define MULT(a,b) ((a)*(b))#define PRINT(x) cout << (#x) << ": " << (x);Der Makro-Einsatz sollte aber nicht ubertrieben werden, eigentlich gibt es daf¨ r ¨ urichtige Funktionen. Bei Makros werden z.B. keine Pr¨ fungen durch den Kom- upiler gemacht, daher sind sie fehleranf¨llig. a9.3 Testfragen 1. Was sind Kontrollstrukturen, welche kennen sie ? 2. Bei welcher logischen Bedingung wird eine if-Anweisung ausgef¨ hrt ? u 3. Lassen sich Kontroll-Strukturen verschachteln ? 4. Mit welcher Kontrollstruktur k¨nnen wir Fallunterscheidungen program- o mieren ? 5. Welche Ausdr¨ cke k¨nnen wir bei der switch-case Kontrollstruktur be- u o nutzen ? 6. Wie kann ich eine Kompiler-Direktive an- und ausschalten ?
    • 9.3 TESTFRAGEN 79 ¨ 7. Schreiben sie die Ubung 9.2.2.2 f¨ r die Benutzung von #ifndef anstelle u von #ifdef um. 8. Erl¨utern sie den Kopf der for-Schleife: for(int i=0;i<stop;i++), wel- a chen Daten-Typ hat stop ? 9. Was ist eine Endlos-Schleife, wie kommen wir daraus ? 10. Was sind Namensbereiche ? 11. Was m¨ ssen wir tun, um die Arbeit mit C++ Standard-Klassen zu verein- u fachen, d.h anstelle von std::my string() direkt my string() benutzen zu k¨nnen ? o 12. Was sind Kompiler-Direktiven, was bewirken diese ? 13. Wie k¨nnen wir Kompiler-Direktiven an- und ausschalten ? o 14. Worin besteht der Unterschied bei Includes mit eckigen Klammern < ... > bzw. mit G¨nsef¨ ßchen ”...” ? a u ¨ 15. Schreiben sie die Ubung 9.2.2.2 f¨ r die Benutzung von #ifndef anstelle u von #ifdef um ? 16. Was sind Makros ? 17. Welche beiden Einsatzm¨glickeiten von Makros gibt es ? o 18. Worin besteht die Gefahr, Makros als Funktionsersatz zu benutzen ?
    • Part IIVisual C++Wir kommen zur grafischen Programmierung - ’Visual C++’. Leider m¨ ssen wir uuns nun f¨ r ein Betriebssystem entscheiden, da die Grafikprogrammierung platt- uformabh¨ngig ist. Es gibt zwar auch plattformunabh¨ngige Grafik-Bibliotheken a aaber die kosten aber in der Regel ... Die Entscheidung ist nicht leicht (die Mac’sund Ubuntu’s werden jetzt zu Recht schimpfen) aber sie f¨ hrt unweigerlich zu uWindows. Die Ideen und Techniken der Grafik-Programmierung sind gr¨ßten- oteils unabh¨ngig vom Betriebssystem, so werden auch die nicht-Windows’ler aeine Menge lernen. Man kann Windows unter Ubuntu emulieren, na schauenwir mal (siehe Anlage 12.7) ... Mittlerweile gibt es auch plattformunabh¨ngige aGrafik-Bibliotheken wie z.B. Qt (siehe Anlage 11) die open source sind.Abbildung 9.1: Eine der bekanntesten Dialog-Applikationen: Der RAR-Packer
    • 9.3 TESTFRAGEN 81Prinzipiell gibt es folgende Konzepte f¨ r die Grafik-Programmierung: u • Dialoge (Abschn. 10), • Dokumente und Ansichten (Doc-View concept), • und nat¨ rlich diverse Kombinationen. uEine typische Dialog-Applikation ist z.B. der RAR-Packer zum Komprimie-ren von Dateien unter Windows (Abb. 9.1). MS-Word ist eine Anwendung desDoc-View-Konzepts, dabei k¨nnen gleichzeitig mehrere Dokumente (d.h. Word- oDateien) ge¨ffnet und bearbeitet werden (Abb. 9.2) o Abbildung 9.2: Eine der bekanntesten Doc-View-Applikationen: MS Word
    • Kapitel 10DialogeDialoge geh¨ren zu den einfachsten Anwendungen von grafischen Benutzer- oschnittstellen (GUI graphical user interface). Ihre Aufgabe ist, es eine grafisch-gest¨ tzte Interaktion (Dialog) mit einem Programm zu erm¨glichen. Wir besch¨fti- u o agen uns mit drei Varianten grafische Dialoge zu produzieren: • dem MFC Dialog (Abschn. 10.1), • dem .NET Formular (Abschn. 10.4), • dem Qt Dialog (Abschn. 11).Mit dem .NET Formular m¨ ssen wir uns ’notgedrungen’ besch¨ftigen, da die u afreien Express Editionen von VC++ (2005 und 2008) die Microsoft-Foundation-Classes (MFC) nicht mehr unterst¨ tzen. Die Erzeugung der leeren Dialoganwen- udungen mit MFC, .NET und Qt finden sie in der Anlage.10.1 What have we (i.e. MFC) created ?Finden sie es nicht auch etwas unheimlich, mit 5 Maus-Klicks etwas kreiert zuhaben, was sich auf unserem Bildschirm hin- und her verschieben l¨sst (Ab- aschn. 12.5) ... Schauen wir uns in Ruhe an, was VC++ f¨ r uns erledigt hat. uDer ’Solution-Explorer’ auf der rechten Seite von VC++ (Abb. 10.1) gibt unsAufschluss uber den automatisch erzeugten Code. Den kompletten Quellcode ¨ ¨der leeren Dialog-Anwendung finden sie in der Ubung E10.1. 82
    • 10.1 WHAT HAVE WE (I.E. MFC) CREATED ? 83. Abbildung 10.1: Der ’Solution-Explorer’ • Header Files: wie gewohnt, unsere Klassen-Definitionen, • Resource Files: neu, unsere grafischen Elemente, • Source Files: unser aktives Bet¨tigungsfeld zum Programmieren. a • ReadMe.txt: ... endlich eine Erkl¨rung, es lohnt sich diese ReadMe-Datei a zu lesen.oder file-m¨ßig aufgedr¨selt: a o • MyDialog.*: Die Windows-Applikation • MyDialogDlg.*: Unser Ding, • Resource.h: Die IDs unserer grafischen Elemente (wird automatisch ak- tualisiert ...), • stdafx.*: Irgendwas, das Windows standartm¨ßig braucht ... aDie Abb. 10.2 soll illustrieren, was VC++ f¨ r uns freundlicherweise erzeugt hat. u • MyDialog.cpp/h enth¨lt die Windows-Applikation, die erzeugt und ruft a den Dialog auf: CMyDialogApp::InitInstance(). • MyDialog.rc ist die Dialog-Resource, der grafische Dialog mit seinen Ele- menten. Dialog-Resourcen und Dialog-Elemente werden uber Nummern ¨ (IDD/IDs) zugeordnet.
    • 84 KAPITEL 10 DIALOGE IDD_MYDIALOG Dialog Resource Funktionen ‘hinter’ den Dialog-Elementen Windows Application MyDialogDlg.cpp/h MyDialog.cpp/h Abbildung 10.2: What have ’we’ created? • MyDialogDlg.cpp/h enth¨lt alle Funktionen des Dialogs, also das was hin- a ter den Kn¨pfchen steckt ... oDie Windows-Applikation macht nichts anderes, als den Dialog aufzurufen.CMyDialogApp theApp;BOOL CMyDialogApp::InitInstance(){CMyDialogDlg dlg; // Instanz der Dialog-Klassedlg.DoModal(); // Aufruf des Dialogs
    • 10.2 GESTALTUNG DES DIALOGS 8510.2 Gestaltung des DialogsZum Design des Dialogs bietet MS-VC++ viele M¨glichkeiten. Hierf¨ r benutzen o uwir den Resourcen-Editor (Abb. 10.3). Abbildung 10.3: Die Dialog-Resource und der Dialog-EditorDie Resourcen-Elemente der ToolBox k¨nne einfach auf das Dialog-Feld ’gezo- ogen’ werden (’Drag and drop’). Die Gestaltung des Dialogs (also die Positionenund IDs von jedem Element) ist dann in der Datei Resources.rc gespeichert.
    • 86 KAPITEL 10 DIALOGEResources.rc...IDD_MYFIRSTWINDOWS_DIALOG DIALOGEX 0, 0, 320, 246STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENUEXSTYLE WS_EX_APPWINDOWCAPTION "MyFirstWindows"FONT 8, "MS Sans Serif"BEGIN CONTROL "Geoecology",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,10, 110,54,10 CONTROL "Geology",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,10,124, 42,10 CONTROL "AEG",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON | WS_GROUP, 10,95,31,10 DEFPUSHBUTTON "OK",IDOK,265,230,50,14 PUSHBUTTON "Cancel",IDCANCEL,5,230,50,14 GROUPBOX "Student data",IDC_STATIC,0,0,170,225 GROUPBOX "Students data base",IDC_STATIC,175,0,140,85 GROUPBOX "Biometric picture",IDC_STATIC,175,90,140,135 LTEXT "First name",IDC_STATIC,5,15,33,8 LTEXT "Last name",IDC_STATIC,5,30,34,8 LTEXT "Birthday",IDC_STATIC,5,45,26,8 LTEXT "Matrikel",IDC_STATIC,5,60,26,8 LTEXT "Bank account",IDC_STATIC,5,75,46,8 EDITTEXT IDC_EDIT1,60,15,105,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT2,60,30,105,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT3,60,45,105,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT4,60,60,105,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT5,60,75,105,14,ES_AUTOHSCROLL | WS_DISABLED EDITTEXT IDC_EDIT6,60,205,105,14,ES_AUTOHSCROLL | WS_DISABLED PUSHBUTTON "Read DB",IDC_BUTTON1,180,15,50,14 PUSHBUTTON "Write DB",IDC_BUTTON2,260,15,50,14 LISTBOX IDC_LIST1,180,35,75,45,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP PUSHBUTTON "Add",IDC_BUTTON3,260,35,50,14 PUSHBUTTON "Edit",IDC_BUTTON4,260,50,50,14 PUSHBUTTON "Remove",IDC_BUTTON5,260,65,50,14 LTEXT "Mark",IDC_STATIC,5,205,17,8 LTEXT "Home work I",IDC_STATIC,5,160,41,8 LTEXT "Home work II",IDC_STATIC,5,175,43,8 EDITTEXT IDC_EDIT7,60,145,105,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT8,60,160,30,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT9,60,175,30,14,ES_AUTOHSCROLL LTEXT "e-mail",IDC_STATIC,5,145,19,8 EDITTEXT IDC_EDIT10,95,160,70,14,ES_AUTOHSCROLL EDITTEXT IDC_EDIT11,95,175,70,14,ES_AUTOHSCROLL PUSHBUTTON "Info",IDC_BUTTON7,5,185,50,14END
    • 10.3 PROGRAMMIERUNG DES DIALOGS – MYDIALOGDLG 8710.3 Programmierung des Dialogs – MyDialogDlgUm jetzt mit dem Programmieren unseres Dialogs beginnen zu k¨nnen, m¨ ssen o uwir uns den Zusammenhang zwischen Dialog-Resource (also seine grafische Ge-stalt) mit seinen Elementen (Kn¨pfchen ...) anschauen. Alle Funktionen und oDaten unseres Dialogs befinden sich in der Klasse CMyDialogDlg, die von der(Windows) Basis-Klasse CDialog abgeleitet wird (dies nennt man auch Verer-bung).class CMyDialogDlg : public CDialog10.3.1 Dialog-FunktionenDie alles entscheidende Stelle, die Verbindung zwischen Dialog-Resource undFunktionen erfolgt in der sogenannten MESSAGE MAP (Nachrichten-Schleife) durchdie Anweisung (Abb. 10.6)BEGIN_MESSAGE_MAP(CMyDialogDlg, CDialog)... ON_BN_CLICKED(IDC_BUTTON, OnButtonReadDB)...END_MESSAGE_MAP()die nichts anderes besagt, wenn das Kn¨pfchen IDC BUTTON gedr¨ ckt wird, dann o uf¨ hre die Funktion OnButtonReadDB aus. u ID = IDC_BUTTON CMyDialogDlgResource.h BEGIN_MESSAGE_MAP(CMyDialogDlg, CDialog)#define IDD_DIALOG 129 ...#define IDB_MARTIN_ZIPPEL 201 ON_BN_CLICKED(IDC_BUTTON, OnButtonReadDB)#define IDC_BUTTON 1009 ... END_MESSAGE_MAP()MyDialog.rc Abbildung 10.4: Dialog-Resource und Dialog-Klasse - Teil 1: Funktionen10.3.2 Dialog-DatenWie der Datenaustausch zwischen der Dialog-Resource und der Dialog-Klasseerfolgt, ist in der Abb. 10.7 dargestellt.
    • 88 KAPITEL 10 DIALOGE ID = IDC_EDIT1 CMyDialogDlgResource.h DoDataExchange()#define IDC_EDIT1 1000 ... DDX_Text(pDX, IDC_EDIT1, m_str_FirstName); ... Abbildung 10.5: Dialog-Resource und Dialog-Klasse - Teil 2: DatenDas Entscheidende passiert in der Funktion DoDataExchange(). Hier wird das,was wir z.B. in das Editier-Feld (First name) eintippen an die (string) Variablem strFirstName weitergeben. Aufgepasst, die Datenaustausch-Funktion wirdnicht automatisch aufgerufen, wie die Funktionen in der MESSAGE MAP. Daf¨ r ugibt es einen triftigen Grund, der Datenaustausch kann in beide Richtungenzwischen Dialog und Klasse erfolgen. Wir schauen uns das sp¨ter in der Imple- amentierung des Dialogs genau an.void CMyDialogDlg::DoDataExchange(CDataExchange* pDX){... CDialog::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDIT1, m_strFirstName);...}10.3.3 Implementierung des DialogsMyDialogDlg.hIm Header-File der Klasse erfolgt die Deklaration der Daten und Funktionen.Das Einf¨ gen von neuen Daten-Elementen und Funktionen ist Bestandteil der u¨Ubung 10.3.Schritte f¨ r neue Daten-Elemente: u 1. Erzeugen des Daten-Elements (IDC EDIT1) mit dem Resourcen-Editor (z.B. Editier-Feld), 2. Deklarieren der Dialog-Variable: CString m strFirstName, 3. Datenaustausch zwischen Resource und Variable: DDX Text(pDX, IDC EDIT1, m strFirstName).Schritte f¨ r neue Funktionen: u 1. Erzeugen des Funktions-Elements (IDC BUTTON) mit dem Resourcen-Editor (z.B. Button),
    • 10.3 PROGRAMMIERUNG DES DIALOGS – MYDIALOGDLG 89 2. Deklarieren der Funktion: void OnButtonReadDB(), 3. Verkn¨ pfen von Resource mit Funktion: ON BN CLICKED(IDC BUTTON, OnButtonReadDB). uDas komplette Ergebnis finden sie im Header-File des Dialogs MyDialogDlg.h.class CMyDialogDlg : public CDialog{... // Dialog data CListBox m_STDVector; // Studenten-Liste CString m_strFirstName; // Vorname CString m_strLastName; // Nachname ... // Dialog functions afx_msg void OnButtonReadDB(); // Lesen der DB afx_msg void OnButtonWriteDB(); // Schreiben der DB afx_msg void OnSelchangeList(); // ¨nderungen anzeigen A afx_msg void OnButtonAdd(); // Hinzuf¨gen eines Datensatzes u afx_msg void OnButtonRemove(); // L¨schen eines Datensatzes o afx_msg void OnButtonEdit(); // Editieren eines Datensatzes...};10.3.4 Schnittstelle zwischen Dialog- und Studenten-KlasseIm CPP-File der Klasse (MyDialogDlg.cpp) stehen unsere Funktionen also dieSchnittstelle zwischen dem Dialog und unserer Studenten-Klasse CStudent. Da-her darf nat¨ rlich auch nicht der entsprechende Include fehlen. u#include "student.h"Wir schauen uns nun zwei Funktionen im Detail an, das Lesen der DatenbankOnButtonReadDB() und das Anzeigen der Datens¨tze OnSelchangeList(). Da- abei sehen wir, wie die Interaktion zwischen Dialog und unserer Studenten-Klasse ¨funktioniert. Den kompletten Quelltext finden sie in der Ubung E10.3.Lesen der Datenbank - OnButtonReadDB()Die Funktion hinter dem Kn¨pfchen ’Read DB’ macht drei Dinge: o • File handling, Offen der DB Datei (Details in Abschn. 10.3.5), ¨ • Lesen der DB, dies ist 1-zu-1 unser DB Lesefunktion (Ubung E8.2.2), ¨ • Die Listen-Box (CListBox m STDVector) mit den gelesenen Datens¨tzen a (Namen) wird gef¨ llt u
    • 90 KAPITEL 10 DIALOGEvoid CMyDialogDlg::OnButtonReadDB(){ //------------------------------------------------------- // 1 File handling see section "File handling" //------------------------------------------------------- // 2 Read DB file STDRead((string)file_name); //------------------------------------------------------- // 3 Fill list box CStudent* m_std = NULL; string m_str; for(int i=0;i<std_vector.size();i++) { m_std = std_vector[i]; m_str = m_std->name_first + " " + m_std->name_last; m_STDVector.AddString(m_str.c_str()); }}Anzeigen der Datens¨tze - OnSelchangeList() aWenn wir auf einen Namen in der Listen-Box klicken, wird eine Funktion aus-gef¨ hrt, welche uns die Daten des ausgew¨hlten Studenten anzeigt. u aDiese Funktion besteht aus vier Teilen: • Bestimmen der Position des Mausklicks im der Listen-Box (nSel), • Zugriff auf den Datensatz (m std) aus der DB entsprechend der angeklick- ten Position und Kopieren der Daten in die Daten-Elemente des Dialogs, • Anzeigen des BMPs (Foto) (Details in 10.3.5), • Aktualisieren des Daten-Elemente des Dialogs.void CMyFirstWindowsDlg::OnSelchangeList(){ //-1-------------------------------------------------------------------- int nSel = m_STDVector.GetCurSel(); //-2-------------------------------------------------------------------- if(nSel>-1) { m_std = student_vector[nSel]; m_strFirstName = m_std->name_first.c_str(); m_strLastName = m_std->name_last.c_str(); m_strBirthDay = m_std->birthday.c_str(); m_lMatrikelNumber = m_std->id; m_strEMail = m_std->email.c_str();
    • 10.3 PROGRAMMIERUNG DES DIALOGS – MYDIALOGDLG 91 m_strHomeWorkI_submitted = m_std->home_work_I_submitted.c_str(); m_strHomeWorkI_submitted = m_std->message.c_str(); m_iHomeWorkI = m_std->home_work_I; m_strHomeWorkII_submitted = m_std->home_work_II_submitted.c_str(); m_iHomeWorkII = m_std->home_work_II; m_iCredit = m_std->credit; } //-3-------------------------------------------------------------------- // BMP //-4-------------------------------------------------------------------- UpdateData(FALSE); // Akualisieren der Dialog-Elemente}Sortieren der Datens¨tze - OnBnClickedButtonDBSort() aBeim alphabetischen Sortieren der Datens¨tze k¨nnen wir uns die Sortier-Funktion a oder Listen zu Nutze machen.void CMyDialog::OnBnClickedButtonDBSort(){ STDSort(); UpdateSTDVector();}void STDSort(){ //---------------------------------------------------------------- int i; CStudent* m_std = NULL; list<string>name_list; for(i=0;i<(int)std_vector.size();i++) { m_std = std_vector[i]; name_list.push_back(m_std->name_last); } //---------------------------------------------------------------- name_list.sort(); //---------------------------------------------------------------- // list<string>::const_iterator iterator; iterator = name_list.begin(); string name_last; while(iterator != name_list.end()) { name_last = *iterator; for(i=0;i<(int)std_vector.size();i++) { m_std = std_vector[i]; if(m_std->name_last.compare(name_last)==0)
    • 92 KAPITEL 10 DIALOGE { std_vector_sorted.push_back(m_std); } } ++iterator; }}void CMyDialog::UpdateSTDVector(){ std_vector.clear(); for(int i=0;i<(int)std_vector_sorted.size();i++) { std_vector.push_back(std_vector_sorted[i]); } std_vector_sorted.clear(); UpdateSTDVectorList();}10.3.5 Nutzliche Windows-Funktionen ¨Wir benutzen fertige Windows-Funktionen / MFC Klassen f¨ r die Datei-Auswahl u(CFileDialog) und das Anzeigen von BMPs (DrawBitmap).File handlingCString file_name;CFileDialog fileDlg(TRUE,"dat",NULL,OFN_ENABLESIZING,"DAT Files(*.dat)|*.dat||");if(fileDlg.DoModal()==IDOK){ file_name = fileDlg.GetFileName();}BitmapsDie Schritte zum Zeichnen des BMPs (Fotos) sind folgende: • Auswahl des rechteckigen Zeichenbereichs (CRect rc), • Auswahl des entsprechenden BMPs (IDB BITMAP1), • Zeichnen des ausgew¨hlten BMPs (DrawBitmap()) avoid CMyFirstWindowsDlg::OnButtonReadDB(){... CRect rc; GetClientRect(&rc);
    • 10.3 PROGRAMMIERUNG DES DIALOGS – MYDIALOGDLG 93 rc.top = 160; rc.left= 290; CBitmap m_bmpStudent; m_bmpStudent.DeleteObject(); m_bmpStudent.LoadBitmap(IDB_BITMAP1); DrawBitmap(rc,m_bmpStudent);...}Dies ist die Zeichenfunktion des ausgew¨hlten BMBs. avoid CMyDialogDlg::DrawBitmap(CRect& rc,CBitmap& bm){ CPaintDC dc(this); HBITMAP hbmpOld; CDC dcMem; dcMem.CreateCompatibleDC(&dc); hbmpOld = (HBITMAP)dcMem.SelectObject(bm); GetDC()->BitBlt(rc.left,rc.top,rc.right,rc.bottom,&dcMem,0,0,SRCCOPY); dcMem.SelectObject(hbmpOld);}
    • 94 KAPITEL 10 DIALOGE10.4 Das .NET Formular.NET (sprich dotnet) ist eine von Microsoft entwickelte Software-Plattform. Die-se umfasst eine Laufzeitumgebung, eine f¨ r Programmierer bestimmte Samm- ulung von Klassenbibliotheken (API) und angeschlossene Dienstprogramme (Ser-vices) (Quelle http://de.wikipedia.org/wiki/.NET). Mit .NET soll i.W. auchVereinheitlichung der (MS) Programmiersprachen VisualBasic (VC), C sharp(C#) und C++ erreicht werden. Die Gestaltung des Formulars mit dem Resourcen-Editor (siehe Anlage 12.6) funktioniert genauso so einfach wie bei den MFC-Dialogen (Anlage 10.2). Abbildung 10.6: Die Formular-ResourceIn der ReadMe.txt finden wir eine Beschreibung, was der Anwendungs-Assistentf¨ r uns erstellt hat. u======================================================================== ANWENDUNG: MyForm-Projekt¨bersicht u========================================================================Diese MyForm-Anwendung wurde vom Anwendungs-Assistenten f¨r Sie erstellt. uDiese Datei enth¨lt eine Zusammenfassung dessen, was Sie in jeder der Dateien afinden, aus denen Ihre MyForm-Anwendung besteht.MyForm.vcproj Dies ist die Hauptprojektdatei f¨r VC++-Projekte, die mit dem Anwendungs- u Assistenten generiert werden. Sie enth¨lt Informationen uber die Version von Visual C++, in der die Datei a ¨ generiert wurde, sowie uber die Plattformen, Konfigurationen und ¨ Projektfeatures, die im Anwendungs-Assistenten ausgew¨hlt wurden. aMyForm.cpp Dies ist die Hauptquelldatei der Anwendung.
    • 10.4 DAS .NET FORMULAR 95 Enth¨lt den Code zum Anzeigen des Formulars. aForm1.h Enh¨lt die Implementierung der Formularklasse und a der InitializeComponent()-Funktion.AssemblyInfo.cpp Enth¨lt benutzerdefinierte Attribute zum ¨ndern von Assemblymetadaten. a A/////////////////////////////////////////////////////////////////////////////Weitere Standarddateien:StdAfx.h, StdAfx.cpp Diese Dateien werden verwendet, um eine vorkompilierte Headerdatei (PCH-Datei) mit dem Namen "MyForm.pch und eine vorkompilierte Typendatei mit dem Namen "StdAfx.obj" zu erstellen./////////////////////////////////////////////////////////////////////////////Um eine Funktion anzulegen (z.B. mit einem Doppelklick auf eine Schaltfl¨che) aerstellt der Anwendungs-Assistent einen Funktionsrumpf in der Form1.h vor.F¨ r unsere Formular-Funktionen legen wir besser eine neue Quell-Datei Form1.cpp uan (enspricht MyDialogDlg.cpp f¨ r den MFC Dialog). In der nachfolgenden Ta- ubelle finden sie die Entsprechungen der Funktionen f¨ r MFC-Dialog und .NET- uFormular. Bedeutung MFC-Dialog CMyDialog:: .NET-Formular Form1:: DB lesen OnButtonReadDB button1 Click DS ausw¨hlen a OnSelchangeList listBox1 SelectedIndexChanged DB sortieren OnBnClickedButtonDBSort button2 Click ListBox f¨ llen u UpdateSTDVector listBox1 Fill Tabelle 10.1:Die gute Nachricht ist, unsere eigenen C++ Funktionen k¨nnen wir 1-zu-1 wei- oterverwenden. Andererseits m¨ ssen wir uns mit den neuen Formular-Elementen uund Daten-Typen vertraut machen, wir sehen auch erhebliche Unterschiede inder Nachrichten-Signal-Verarbeitung. Es ist einfacher geworden, es gibt z.B. kei-ne IDs mehr, die grafischen Elemente sind direkte Bestandtteile (member) derFormular-Klasse.10.4.1 FunktionenEine Funktion f¨ r Schaltfl¨che erstellen wir mit einem Doppelklick auf die ent- u asprechende Formular-Resource. Damit generieren wir ein Ereignis button1→Click,das mit einer Funktion vern¨ pft ist. Eine weitere Besonderheit ist, dass das Er- ueignis dynamisch zur Laufzeit erzeugt wird.
    • 96 KAPITEL 10 DIALOGEForm1.h: Verkn¨ pfung von Ereignis (Klick auf button1) und Funktion u.NET: this->button1->Click += gcnew System::EventHandler(this,&Form1::button1_Click); MFC: ON_BN_CLICKED(IDC_BUTTON1, OnButtonReadDB)Die Definition der Klick-Funktion button1 Click in der Quell-Datei ist im fol-genden dargestellt sowie der Vergleich mit der entsprechenden MFC-Funktion.Nat¨ rlich k¨nnen wir die .NET Funktionen auch umbenennen. Nat¨ rlich k¨nnen u o u owir die .NET Funktionen auch umbenennen, z.B. button1 Click in ReadDB. ¨Die Anderung muss an allen Stellen wo der alte Funktionsname button1 Clickauftaucht erfolgen. Keine Angst, der Kompiler meldet sich sofort, wenn sie esirgendwo vergessen haben sollten ...Form1.cpp: Klick-Funktion.NET: Void Form1::button1_Click(System::Object^ sender, System::EventArgs^ e) MFC: void CMyDialog::OnButtonReadDB() ¨Wir sehen uns die Funktion sp¨ter in der Ubung genauer an. a10.4.2 DatenWie schon erw¨hnt, .NET benutzt komplett neue Daten-Typen (Kommentar). aDie Tabelle 10.2 am Ende des Abschnitts gibt einen kleinen Vergleich. Die Hier-archie der Namensr¨ume ist f¨ r .NET Formulare ist: System::Windows::Forms. a uDer Datenaustausch zwischen den Variablen und den Resourcen ist in .NET ein-facher geworden und erfolgt direkt ohn den Umweg uber IDs. Es gibt also keine ¨DDX Datenaustausch-Funktionen mehr.Form1.h:.NET: private: System::Windows::Forms::TextBox^ textBox1; private: System::Windows::Forms::ListBox^ listBox1; MFC: CString m_strFirstName; CListBox m_STDVector; MFC: DDX_Text(pDX, IDC_EDIT1, m_strFirstName); DDX_Control(pDX, IDC_LIST1, m_STDVector);Nachfolgend sehen wir, wie Werte der Variablen an die grafischen Resourcenweitergegeben werden.Form1.cpp:.NET: textBox1->AppendText(name_first_trimmed); listBox1->Items->Add(Str);
    • 10.4 DAS .NET FORMULAR 97 Bedeutung C++ MFC .NET Zeichenkette string CString String^ ListBox - CListBox ListBox Tabelle 10.2: Vergleich von Daten-Typen10.4.3 ¨ Ubung: Hinzufugen von Funktionen ¨ ¨Schritt 1: UberlegenWas wollen wir tun ? Eine Funktion zum Anlegen eines neuen Datensatzeserstellen. Eine perfekte Vorbereitung w¨re es gewesen, diese Funktion bereits ageschrieben und in einem kleinen Konsolenprogramm getestet zu haben ...Schritt 2: Resourcen-Element anlegenDie Schaltfl¨che einfach auf das Formualfeld ziehen (Abb. 10.7). a Abbildung 10.7: Die Formular-Resource bearbeitenUm herauszubekommen, was passiert ist, suchen wir einfach mal nach button3in unserem Projekt. Das Suchergebnis sehen wir in Abb. 10.8.
    • 98 KAPITEL 10 DIALOGE. Abbildung 10.8: What have we createdDie Treffer betreffen ausschließlich die Header-Datei Form1.h. Dort finden wirdie Deklaration der Schaltfl¨che button3 als Daten-Typ Button^ sowie die Defi- anition der dazugeh¨rigen grafischen Resource (Position, Gr¨ße etc.) in der Funk- o otion InitializeComponent().Form1.hWindows Form Designer generated codeprivate: System::Windows::Forms::Button^ button3; // Daten-Typvoid InitializeComponent(void){... this->button3 = (gcnew System::Windows::Forms::Button()); ... // button3 this->button3->Location = System::Drawing::Point(160, 145); this->button3->Name = L"button3"; // andern in L"Add" ¨ this->button3->Size = System::Drawing::Size(75, 23); this->button3->TabIndex = 8; this->button3->Text = L"button3"; this->button3->UseVisualStyleBackColor = true;...}Schritt 3: Funktion anlegenWie schon erw¨hnt, mit einem Doppelklick auf das Resourcen-Element wird die aFunktion automatisch im Header-File angelegt.Form1.hprivate: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) { }In der Parameterliste der Funktion sehen wir ein Objekt sender und EreignisseEventArgs, welche die Nachrichtenliste (message map) in MFC ersetzen.
    • 10.4 DAS .NET FORMULAR 99Schritt 4: Funktion in CPP FileEigentlich k¨nnten wir die Funktion button3 Click auch im Header-File belas- osen. Ich empfehle aber, die Funktion in das CPP-File zu kopieren und nur ihreDeklaration im H-File zu hinterlassen.Form1.h/cppprivate: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e);Void Form1::button3_Click(System::Object^ sender, System::EventArgs^ e){}Schritt 5: Funktion schreibenUnsere Funktion ’hinter dem Kn¨pfchen’ ist erfreulich kurz und enth¨lt folgende o aSchritte: (1) Erzeugen einer neuen Instanz unser Klasse CStudent, (2) Einf¨ gen udieser Instanz in den Datenbank (DB) Vektor, (3) Aktualisieren unserer ListBoxim Formular.Form1.h/cppVoid Form1::button3_Click(System::Object^ sender, System::EventArgs^ e){ CStudent* m_std = new CStudent(); // neue CStudent Instanz std_vector.push_back(m_std); // in Vektor eintragen listBox1_Fill(); // ListBox aktualisieren} Abbildung 10.9: Neuen Datensatz einf¨ gen u
    • 100 KAPITEL 10 DIALOGESchritt 6: Funktion testenDer letzte Schritt ist das Testen der neuen Funktion. Dabei m¨ ssen wir alle uKombinationen von Kn¨pfchen ausprobieren. Der Unterschied von interaktiven ozu Konsolen-Programmen ist, das jede Funktion beliebig oft ausgef¨ hrt wer- uden k¨nnen muss. Daher m¨ ssen vor Ausf¨ hren der Funktion i.d.R. alle Daten o u ugel¨scht und wieder neu erzeugt werden. o Abbildung 10.10: DB sortierenDie soll zur MS-Windows-Programmierung mit MFC und .NET gen¨ gen, um uihnen den ’flavour’ vermittelt zu haben.
    • 10.5 HOMEWORKS 10110.5 HomeWorksMFC (obsolet f¨ r VC++ Express) u 1. Implementieren sie die Funktion zum Einf¨ gen eines neuen Datensatzes – u CMyDialogDlg::OnButtonAdd(). 2. Implementieren sie die Funktion zum L¨schen eines Datensatzes – o CMyDialogDlg::OnButtonRemove(). 3. Implementieren sie die Funktion zum Editieren eines Datensatzes – CMyDialogDlg::OnButtonEdit(). 4. Implementieren sie die Funktion zum Schreiben der Datenbank – CMyDialogDlg::OnButtonWriteDB(). 5. Bauen sie einen Z¨hler f¨ r die Anzahl der existierenden Datens¨tze ein. a u a Hinweis: Benutzen sie dazu ein Editier-Feld..NET 1. Implementieren sie die Funktion zum L¨schen eines Datensatzes – o button4 Click. 2. Implementieren sie die Funktion zum Editieren eines Datensatzes – button5 Click. 3. Implementieren sie die Funktion zum Schreiben der Datenbank – button5 Click. 4. Bauen sie einen Z¨hler f¨ r die Anzahl der existierenden Datens¨tze ein. a u a Hinweis: Benutzen sie dazu ein Editier-Feld.
    • 102 KAPITEL 10 DIALOGE10.6 TestfragenMFC 1. Welche Typen von grafischen Windows-Applikationen kennen sie ? 2. Was ist eine Dialog-Resource ? 3. Welche Dialog-Elemente haben wir in unserer Windows-Applikation be- nutzt (Abb. 10.3) ? 4. Was sind IDs ? 5. Was ist eine MESSAGE MAP ? 6. Wie wird die Verbindung zwischen Funktionen und grafischen Dialog- Elementen hergestellt ? 7. Wie wird die Verbindung zwischen Daten und grafischen Dialog-Elementen hergestellt ? 8. Was bedeutet die Definition: class CMyDialog : public CDialog ? 9. Wie wird ein Dialog aufgerufen (Funktion der Klasse CDialog)? 10. Was bewirkt die Dialog-Funktion UpdateData() ? 11. Was ist die Schnittstelle zwischen dem Dialog und unserer Studenten- Klasse ? 12. Wie kann ich Files unter Windows ¨ffnen (welche Klasse) ? o 13. Was ist ein BMP ?.NET 1. Was ist eine Formular-Resource ? 2. Welche Formular-Elemente haben wir in unserer .NET-Applikation be- nutzt (Abb. 10.10) ? 3. Wie wird die Verbindung zwischen Funktionen und grafischen Formular- Elementen hergestellt ? 4. Wie wird die Verbindung zwischen Daten und grafischen Formular-Elementen hergestellt ? 5. Was bedeutet die Definition: private: System::Windows::Forms::Button MyButton ? 6. Was bedeutet die Definition: private: System::Void button3 Click() ?
    • 10.6 TESTFRAGEN 103 7. Wie wird ein Formular aufgerufen (Funktion der Klasse Form1)? 8. Was ist die Schnittstelle zwischen dem Dialog und unserer Studenten- Klasse ? 9. Wie kann ich Files mit .NET ¨ffnen (welche Klasse) ? o
    • Kapitel 11QtDie Panne mit dem Dialog war echt nicht geplant, d.h. dass MFC Dialoge mitder freien MSVC++ Express Version nicht mehr verf¨ gbar sind. Dies zeigt uns uaber, auch beim Programmieren niemals nur auf ein Pferd setzen. Wichtig ist,unser eigener Code muss C++ Standard sein, den k¨nnen wir dann problemlos oin verschiedene GUI Frameworks, wie MSVC++, Qt etc. einbauen. ¨Warum jetzt noch Qt ? Wir werden in den Ubungen sehen, dass Qt sehr dichtan C++ Standards dran ist und Qt ist ’a cross-platform GUI’. Qt l¨uft auf Win- adows, Linux, Mac ... In der Anlage 12.8 finden sie eine Anleitung zur Installationvon Qt.11.1 Hello QtWie es sich f¨ r ein ordentliches Programmier-Framework geh¨rt, ist die erste u o¨Ubung ”Hello World” auf graphisch.¨Ubung: 11.1#include <QApplication>#include <QLabel>int main(int argc, char *argv[]){ QApplication app(argc,argv); QLabel *label = new QLabel("Hello Qt!"); label->show(); return app.exec();}Sehr erfreulich ist die N¨he von Qt zum Standard C++, es gibt eine klassische amain() Funktion. Die Komposition von ”Hello Qt” ist sehr einfach: 104
    • 11.2 EXECUTABLE 105 • Es wird eine Qt Application angelegt (¨hnlich wie bei Windows, aber doch a irgendwie einfacher), • Es wird ein Label angelegt, das mit der Methode →show() angezeigt wird.Qt bietet auch die M¨glichkeit, einfach HTML code zu integrieren. Ersetzen sie odie QLabel Zeile wie folgt. QLabel *label = new QLabel("<h2><i>Hello<!i>""<font color=red>Qt!</font></h2>"); Abbildung 11.1: Hallo Qt11.2 ExecutableUm ein ausf¨ hrbares Qt Programm zu erzeugen ben¨tigen wir 3+1 Schritte: u o • Gehen sie in ihre Start - Programme Men¨ (Windows) und starten sie die u den Qt command prompt (Fig. 11.2). Abbildung 11.2: Qt Kommando Zeile • Mit qmake -project erzeugen sie ein Qt Projekt. • Mit qmake legen sie ein makefile an. • Mit mingw32-make (kein Leerzeichen) kompilieren sie das Projekt und generieren ein ausf¨ hrbares Programm. u • Mit E10 1 HelloQt.exe starten sie das Programm.
    • 106 KAPITEL 11 QT. Abbildung 11.3: Die Schritte in Bildern ...11.3 Quit a ¨Die n¨chste Ubung zeigt uns, wie einfach mit Schaltfl¨chen (Push Button) ge- aarbeitet werden kann.#include <QApplication>#include <QPushButton>int main(int argc, char *argv[]){ QApplication app(argc,argv); QPushButton *button = new QPushButton("Quit"); QObject::connect(button, SIGNAL(clicked()),&app, SLOT(quit())); button->show(); return app.exec();}Im Unterschied zu ”Hello Qt” ist eine Kommunikation mit dem Anwender(dr¨ cken der Schaltfl¨che) notwendig. Die Signalverarbeitung erfolgt uber die u a ¨Object-Methode connect. QObject::connect(button, SIGNAL(clicked()),&app, SLOT(quit()));
    • 11.4 DIALOG 107Dabei wird die Nachricht SIGNAL(clicked()) mit der Schaltfl¨che Quit mit aeinem sogenannten SLOT(quit())) verbunden. Abbildung 11.4: Hallo Qt11.4 DialogZum Abschluss unsere Dialog-Anwendung. Dabei wird in der main Funktioneine Instanz der Klasse QDialog erzeugt.#include <QtGui/QApplication>#include "dialog.h"int main(int argc, char *argv[]){ QApplication a(argc, argv); Dialog w; w.show(); return a.exec();}Der Header des Dialogs enth¨lt im Wesentlichen die Resourcen-Elemente, z.B. adie Schaltfl¨che pushButtonReadDB zum Lesen der Datenbank sowie die dazu- ageh¨rigen Funktionen on pushButtonReadDB clicked(). oclass Dialog : public QDialog{ Q_OBJECTpublic: Dialog(QWidget *parent = 0); ~Dialog();private: Ui::Dialog *ui; QListWidget *listWidget; QPushButton *pushButtonReadDB; QPushButton *pushButtonAdd; QPushButton *pushButtonDelete;
    • 108 KAPITEL 11 QT QLineEdit *lineEditNameFirst; QLineEdit *lineEditNameLast;private slots: void on_pushButtonReadDB_clicked(); void on_pushButtonAdd_clicked(); void on_pushButtonDelete_clicked(); void on_listWidget_clicked();};Die Implementierung des Dialogs besteht aus drei Teilen: 1. Konstruktion der grafischen Resourcen-Elemente: pushButton (Schaltfl¨chen), a listWidget (Liste), lineEdit (Editierfelder), 2. Signalverarbeitung: Wenn pushButtonReadDB gedr¨ ckt wurde, f¨ hre die u u Funktion on pushButtonReadDB clicked aus, 3. Layout: Es werden horizontale und vertikale Boxen angelegt.Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog){ ui->setupUi(this); // 1.1 - pushButton pushButtonReadDB = new QPushButton(tr("&Read DB")); pushButtonAdd = new QPushButton(tr("&Add DS")); pushButtonDelete = new QPushButton(tr("&Delete DS")); // 1.2 - listWidget QString name = "Tom Hanks"; QStringList names; names << name << "Alice Wunderland" << "Bob Dylan" << "Carol Crow" << "Donald Dug" << "Emma Thomson"; listWidget = new QListWidget(); for (int row = 0; row < 5; ++row) { listWidget->addItem(names[row]); } //1.3 - lineEdit lineEditNameFirst = new QLineEdit(); lineEditNameFirst->insert("Tom"); lineEditNameLast = new QLineEdit(); lineEditNameLast->insert("Hanks"); // 2 - connect connect(pushButtonReadDB,SIGNAL(clicked()),this,SLOT(on_pushButtonReadDB_clicked())); connect(pushButtonAdd,SIGNAL(clicked()),this,SLOT(on_pushButtonAdd_clicked())); connect(pushButtonDelete,SIGNAL(clicked()),this,SLOT(on_pushButtonDelete_clicked())); connect(listWidget,SIGNAL(itemSelectionChanged()),this,SLOT(on_listWidget_clicked())); //3 - Layout
    • 11.4 DIALOG 109 QHBoxLayout *leftTopLayout = new QHBoxLayout; leftTopLayout->addWidget(lineEditNameFirst); leftTopLayout->addWidget(lineEditNameLast); QVBoxLayout *leftLayout = new QVBoxLayout; leftLayout->addLayout(leftTopLayout); leftLayout->addWidget(listWidget); QVBoxLayout *rightLayout = new QVBoxLayout; rightLayout->addWidget(pushButton); rightLayout->addWidget(pushButtonAdd); rightLayout->addWidget(pushButtonDelete); rightLayout->addStretch(); QHBoxLayout *mainLayout = new QHBoxLayout; mainLayout->addLayout(leftLayout); mainLayout->addLayout(rightLayout); setLayout(mainLayout);}Das Ergebnis der Dialog-Implementierung sehen wir in Abb. 11.5. Abbildung 11.5: Qt DialogUm zu pr¨ fen, ob die Signalverarbeitung hinter den Kn¨pfchen funktioniert, u orufen wir eine MessageBox auf.void Dialog::on_pushButtonAdd_clicked(){ QMessageBox msgBox; msgBox.setText("pushButtonAdd clicked"); msgBox.exec();}
    • 110 KAPITEL 11 QTDies soll als kurze Einf¨ hrung in Qt erstmal gen¨ gen, es geht weiter im n¨chsten u u aSemester.
    • Part IIIAnlagen / Software
    • Kapitel 12Software-Installation 112
    • 12.1 CYGWIN INSTALLATION 11312.1 cygwin InstallationIn dieser Anlage finden sie eine Anleitung zur Installation von cygwin - dies isteine Linux-Umgebung f¨ r Windows. In dieser Umgebung k¨nnen sie die GNU u oC und C++ Compiler verwenden.Abbildung 12.1: Schritt 1: Gehen sie auf cygwin Web Seite - www.cygwin.com.Klicken sie auf das cygwin Symbol (Install or update now!).Abbildung 12.2: Schritt 2: Laden sie die setup.exe Datei auf ihren Rechnerherunter und f¨ hren sie die setup.exe aus. u
    • 114 KAPITEL 12 SOFTWARE-INSTALLATION.Abbildung 12.3: Schritt 3: Das cygwin setup Programm wird gestartet. Hier se-hen sie auch die aktuelle Versionsnummer (2.573.2.3). Best¨tigen sie mit Weiter. aAbbildung 12.4: Schritt 4: W¨hlen sie das Verzeichnis zur Installation von acygwin aus, z.B. das Verzeichnis, in dem die Anwendungsprogramme sind(C:/Programme). Behalten sie die Voreinstellungen. Best¨tigen sie mit Weiter. a
    • 12.1 CYGWIN INSTALLATION 115.Abbildung 12.5: Schritt 5: cygwin ben¨tigt ein tempor¨res Verzeichnis f¨ r die o a uInstallation, das sp¨ter gel¨scht werden kann. Behalten sie die Voreinstellungen. a oBest¨tigen sie mit Weiter. aAbbildung 12.6: Schritt 6: Benutzen sie die voreingestellte direkte Internetver-bindung. Best¨tigen sie mit Weiter. a
    • 116 KAPITEL 12 SOFTWARE-INSTALLATION.Abbildung 12.7: Schritt 7: W¨hlen sie die download site, am besten die Dresdner: ahttp://ftp.inf.tu-dresden.de; Best¨tigen sie mit Weiter. aListe der 6 zu installierenden Pakete aus der Kategorie ’Devel’: • binutils: The GNU assembler linker and binary utilities (release 20080624- 2) [6MB] • gcc-core: C compiler (release 3.4.4.999) [3.6MB] • gcc-g++: C++ compiler (release 3.4.4.999) [7.8MB] • gcc-mingw-core: support headers and libraries for GCC (release 20050522- 1) [69kB] • gcc-mingw-g++: support headers and libraries for GCC C++ (release 20050522-1) [1.9MB] • mingw-runtime library (release 3.15.2-1) [372kB]
    • 12.1 CYGWIN INSTALLATION 117.Abbildung 12.8: Schritt 8: Nun erscheint die Liste der packages, die installiert ¨werden k¨nnen. Offnen sie dem Baum Devel (klicken Sie auf das Plus-Symbol). oW¨hlen sie die oben aufgef¨ hrten Pakete aus, welche f¨ r die Installation von C a u uund C++ ben¨tigt werden. Best¨tigen sie mit Weiter. o aDie nachfolgenden Abbildungen zeigen ihnen, welche Markierungen aktiviertsein m¨ ssen, um den C (GCC) und den C++ (G++) zu installieren. Eigentlich ureicht es, die binutils, gcc-core und gcc-g++ auszuw¨hlen, die restlichen aPakete (mingw) m¨ ssten automatisch aktiviert werden. Egal, uberpr¨ fen sie, ob u ¨ ualles wie in den nachfolgenden Abbildungen markiert ist. Viel Erfolg!
    • 118 KAPITEL 12 SOFTWARE-INSTALLATION. Abbildung 12.9: Schritt 8a: (aktive) Auswahl der binutils Abbildung 12.10: Schritt 8b: (aktive) Auswahl der C und C++ CompilerDie nachfolgenden Pakete sollte automatisch markiert werden, bitte uberpr¨ fen ¨ usie dies sicherheitshalber.
    • 12.1 CYGWIN INSTALLATION 119. Abbildung 12.11: Schritt 8c: (automatische) Auswahl von Hilfspaketen Abbildung 12.12: Schritt 8d: (automatische) Auswahl von HilfspaketenAbbildung 12.13: Schritt 9: Behalten sie die Voreinstellungen, um eine cygwinVerkn¨ pfung auf ihrem desktop zu erstellen. Schließen sie die Installation ab. u
    • 120 KAPITEL 12 SOFTWARE-INSTALLATIONIm Ergebnis der Installation erhalten sie eine desktop Verkn¨ pfung mit cygwin, udas nun mit einem Doppelklick gestartet werden kann. Abbildung 12.14: Schritt 8d: cygwin desktop Verkn¨pfung uStarten sie cygwin mit einem Doppelclick auf die desktop Verkn¨pfung. u Abbildung 12.15: Start von cygwinMit einem Rechtsklick auf den oberen Balken gelangen sie in das Eigenschaften-Menu und k¨nnen Einstellungen (z.B. Farben) nach ihrem Geschmack andern. o ¨
    • 12.1 CYGWIN INSTALLATION 121. Abbildung 12.16: Das Eigenschaften-Menu von cygwinTesten sie, ob die Compiler einsetzbar sind, indem sie diese einfach aufrufen: • gcc - Aufruf des C Compilers • g++ - Aufruf des C++ CompilersDa sie die Compiler ohne etwas zu tun aufrufen, erhalten sie die Meldung: keineEigabedateien. Abbildung 12.17: Aufruf der CompilerNun kann es also endlich losgehen mit der ersten Ubung ⇒ Abschnitt 1.4. ¨
    • 122 KAPITEL 12 SOFTWARE-INSTALLATION12.2 LINUX12.2.1 ¨ Ubersicht einiger grundlegenden Linux-Befehle Befehl / command Bedeutung Hilfe man Klassische Hilfe (verlassen mit Q) info Online Hilfe von GNU (verlassen mit Q) apropos Schl¨ sselw¨rtersuche bei “man“-Seiten u o whatis Kurzbeschreibung zu einem Kommando oder Schl¨ sselwort u Dateien ls Dateien auflisten ls -attr Dateiattribute auflisten file Dateityp ermitteln cp Quelle Ziel Kopiert Quelle nach Ziel mv Datei1 Datei2 Datei1 umbenennen in Datei2 mv Datei V1 Verschiebt Datei in das Verzeichnis V1 rm Dateien Dateien l¨schen o rmdir Verzeichnis Verzeichnis l¨schen o find Suche nach Dateien find/ Suche startet im Root-Verzeichnis / im ganzen System Verzeichnisse pwd gibt aktuelles Arbeitsverzeichnis an ./ aktuelles Verzeichnis cd Wechsel des aktuellen Verzeichnisses mkdir ein Verzeichnis anlegen rm Verzeichnis ein Verzeichnis l¨schen o rmdir ein leeres Verzeichnis l¨schen o ls Verzeichnisinhalt auflisten Systembefehle shutdown -h Herunterfahren des Systems shutdown Uhrzeit Herunterfahren des Systems bei Uhrzeit (z.B.: 14.00) shutdown -t Sekunden Herunterfahren des Systems nach Anzahl der Sekunden reboot oder shutdown -r Neustart des Systems uname Systeminformationen ausgeben ¨Diese Ubersicht basiert auf ’Linux auf einem Blatt’ von Christian Helmbold(www.helmbold.de) (siehe n¨chste Seite) a
    • 12.2 LINUX 123weitere Informationen und Erkl¨rungen a ¨deutsche Ubersichten: ¨- Pdf-Ubersicht ’Linux auf einem Blatt’ (auch zum Download)www.helmbold.de/linux- Linux-Befehle f¨ r Einsteiger uhttp://www.linux-fuer-alle.de/doc show.php?docid=33 ¨- Ubersicht f¨ r wichtige Linux-Befehle und Programme uhttp://www.tnt-computer.de/yanip/lbefehle.html ¨englische Ubersichten ¨- umfangreiche Ubersicht mit Parametern und Beispielenhttp://www.computerhope.com/unix.htm#04- Vergleich zwischen MS-DOS- und Linux-Befehlenhttp://www.yolinux.com/TUTORIALS/unix for dos users.htmlWir arbeiten uns jetzt mal mit der online-Hilfe ’man’ (steht f¨ r Manual) weiter uvor. Abbildung 12.18: Benutzen der online HilfeMit dem Befehl man ls k¨nnen wir uns die Optionen von ls (Dateien auflisten) oanzeigen lassen.
    • 124 KAPITEL 12 SOFTWARE-INSTALLATION. Abbildung 12.19: Optionen von ls (Dateien auflisten)
    • 12.2 LINUX 12512.2.2 ProfileWir n¨hern uns der L¨sung, einfach in das Verzeichnis zu gelangen, in dem sich a o ¨ ¨unsere Ubungen befinden. Ahnlich wie in DOS die Programme autoexec.batund config.sys beim Start des Betriebsystems automatisch ausgef¨ hrt werden, uist es bei LINUX ein so genanntes Profile: .bash profile. In diese Datei k¨nnen oeigene Befehle eingetragen werden.Eigentlich ist es ganz einfach ....cd C:/User/TEACHING/C++/EXERCISESDurch diese Instruktion in der .bash profile wechseln wir direkt in das Ver- ¨zeichnis, in dem sich unsere Ubungen befinden.Nachdem wir verschiedene Editoren ausprobiert haben (und erhebliche Unter-schiede in der Behandlung von Zeilenenden (CR) gesehen haben), ließ sich zu ¨allem Ubel unsere m¨ hsam editierte .bash profile mit dem Windows-Explorer unicht speichern (es liegt an dem Punkt am Anfang des Datei-Namens). Ich kannihre Entt¨uschung gut verstehen, nicht umsonst gibt es Windows und Linux- aAnh¨nger. Dennoch m¨ ssen wir eine L¨sung finden oder ? a u o12.2.2.1 L¨sung 1: unix2dos oNach unserem Schiffbruch mit dem Speichern einer ’.bash profile’ unter Win-dows (’denkt’ vor dem Punkt kommt der Datei-Name und nach dem Punkt dieFile-Extension, also nix vor dem Punkt heißt f¨ r Windows, kein Datei-Name ... uso ist das, wenn Programme zu viel denken).Die zweite L¨sung ist eine Dateikonvertierung. Linux bietet zwei Programme an: odos2unix und unix2dos, mit denen man Dateien plattformgerecht konvertierenkann (Fig. 12.20) Abbildung 12.20: Wandeln zwischen Linux und Dos-Dateien
    • 126 KAPITEL 12 SOFTWARE-INSTALLATION12.2.2.2 L¨sung 2: Cygwin (the Linux point of view) oWir brauchen einen ’einfachen’ Editor f¨ r cygwin, d.h. wir m¨ ssen nachinstal- u ulieren (siehe Abschn. ) Abbildung 12.21: Nachinstallieren des vi EditorsNach der vi Installation m¨ ssen wir in das Verzeichnis (home directory) gelan- ugen, wo sich die .bash profile Datei befindet. Abbildung 12.22: home directory und dessen Inhalt
    • 12.2 LINUX 127Wir ¨ffnen die .bash profile Datei mit dem vi Editor wie folgt: o Abbildung 12.23: Starten des vi EditorsJetzt k¨nnen wir mal einen Linux-Editor live erleben (danach werden sie Win- o ¨dows noch mehr ’lieben’ ...). Nach dem Offnen der Datei gehen sie mit demKursor dorthin, wo sie Text einf¨ gen m¨chten. Dann dr¨ cken sie die ’i’ Taste, u o uder insert Modus wird gestartet. Nun k¨nnen sie den Befehl zum Wechseln in ihr o¨ ¨Ubungsverzeichnis eingeben cd ... Um die Anderungen zu speichern, dr¨ cken sie u’Esc’ ’:’ ’w’. vi wechselt nun in den File-Modus ’w’ steht f¨ r write ... so einfach uist das. Abbildung 12.24: Editieren und speichern
    • 128 KAPITEL 12 SOFTWARE-INSTALLATION Befehl Wirkung i Wechseln in den Insert/Einf¨ ge-Modus u a Wechseln in den Append/Anh¨ngen-Modus a Esc: Wechseln in den Kommando-Modus w Write: Datei speichern (im Kommando-Modus) q ¨ Quit: Datei ohne Anderung verlassen (im Kommando-Modus) q! ¨ Quit: Datei ohne Anderung verlassen (im Kommando-Modus)12.2.3 MakeMit den Make utilities k¨nnen ganze Projekte kompiliert werden, die aus vielen oQuelltext-Dateien bestehen. Nachfolgend sehen sie die Instruktionen des ma-kefile f¨ r die Kompilierung unseres Projekts. Dabei werden die Quell-Dateien umain.cpp und student.cpp kompiliert, gelinkt und die ausf¨ hrbare Datei a.exe uerzeugt.#OPTFLAG = -O3C++ = g++ $(OPTFLAG) -WallCFile = main.cpp student.cppOFile = main.o student.o.SUFFIXES: .o .cpp .h.cpp.o:$(C++) -c -o $*.o $<main: $(OFile)$(C++) -o main $(OFile)clean:rm -f *.o
    • ¨12.3 SCHUSSELWORTE IN C++ 12912.3 Schusselworte in C++ ¨ ¨Die nachfolgende Tabelle gibt ihnen eine Uberblick der C++ Schl¨ sselworte. uWir werden die Tabelle sukzessive f¨ llen aber nicht alle Keywords benutzen. u Keyword Bedeutung Benutzung im Kapitel bool Datentyp 2 char Datentyp 2 double Datentyp 2 float Datentyp 2 int Datentyp 2 long Datentyp 2 short Datentyp 2 void Datentyp 2 wchar t Datentyp 2 Tabelle 12.1: Schl¨ sselworte u
    • 130 KAPITEL 12 SOFTWARE-INSTALLATION12.4 MS VC++ Projekt #1 - Eine Konsolenan- wendungIn dieser Anlage finden sie eine Anleitung zur Erstellung eines MS VC++ Pro-jekts. Abbildung 12.25: Schritt 1: Starten sie MS Visual Studio (MSVS)
    • 12.4 MS VC++ PROJEKT #1 - EINE KONSOLENANWENDUNG 131.Abbildung 12.26: Schritt 2: Gehen sie zu File - New und w¨hlen sie ’Project afrom existing code’Abbildung 12.27: Schritt 3: W¨hlen sie ein ’Visual C++’ Projekt. Sie sehen, adass mit MSVS auch andere Projekte (z.B. Java) erzeugen k¨nnen o
    • 132 KAPITEL 12 SOFTWARE-INSTALLATION.Abbildung 12.28: Schritt 4: Richten sie am besten vorher ein neues Unterver-zeichnis ein, in dem die Projektdateien gespeichert werden sollen ... es werdeneinige Dateien sein. Kopieren sie das/die Quell-Files (hier copy.cpp) in diesesVerzeichnis. W¨hlen sie mit ’Browse’ (nur) das Verzeichnis aus und vergeben asie einen Projektnamen (hier ’msvcp1’). Gehen sie weiter ’next’Abbildung 12.29: Schritt 5: W¨hlen sie als Projekt-Typ ’Console application aproject aus’. (Sp¨ter werden wir auch Windows-Applikationen erstellen, nur aGeduld). Schließen sie ab ’finish’
    • 12.4 MS VC++ PROJEKT #1 - EINE KONSOLENANWENDUNG 133.Abbildung 12.30: Nun m¨ ssten sie folgendes Bild sehen. Der ’solution explorer’ uauf der linken Seite zeigt ihnen ihr Projekt ’msvcp1’ an und hat automatischdas Quell-File copy.cpp in das Projekt eingetragen.Abbildung 12.31: Wenn wir in unser Projekt-Verzeichnis schauen, sehen wir,dass MSVS einige Dateien f¨ r uns angelegt hat. Das eigentlich Projekt-File ist: umsvcp1.vcproj. Mit einem Doppelklick darauf wird das Projekt geladen.Das war’s erstmal.
    • 134 KAPITEL 12 SOFTWARE-INSTALLATION12.5 MFC-DialogDialoge geh¨ren zu den einfachsten Anwendungen von grafischen Benutzer- oschnittstellen (GUI graphical user interface). Ihre Aufgabe ist, es eine grafisch-gest¨ tzte Interaktion (Dialog) mit einem Programm zu erm¨glichen. In der u oAnlage finden sie die entsprechenden Schritte f¨ r die Dialog-Anwendung mit uVC++2005 Abbildung 12.32: Starten von VC++2005Nach dem Starten von VC++ (Fig. 12.32) m¨ ssen wir ein neues Projekt anlegen u(Fig. 12.33).
    • 12.5 MFC-DIALOG 135. Abbildung 12.33: Klick 1: Neues Projekt anlegenW¨hlen sie ’MFC Application’ aus. W¨hlen Sie im unteren Teil des Dialogs (Fig. a a12.34) das Verzeichnis f¨ r ihr Dialog-Projekt und geben sie ihm einen Namen. uDer ’Projektgruppen-Name’ wird automatisch vergeben. Abbildung 12.34: Klick 2: MFC Applikation ausw¨hlen a
    • 136 KAPITEL 12 SOFTWARE-INSTALLATION. Abbildung 12.35: Klick 3: Einfach weiter (next)W¨hlen sie ’Dialog based’ und ihre Sprache aus (Abb. 12.36) und schließen sie aab (Finish).Abbildung 12.36: Klick 4: Auswahl des Applikations-Typs (Dialog, SDI, MDI)
    • 12.5 MFC-DIALOG 137In dem Moment, wenn sie ’Finish’ dr¨ cken (Klick 5), wird der gesamte Quell- uCode f¨ r ihre Dialog-Anwendung erzeugt. Mit ’Ctrl-F5’ oder Debug → ’Start uwithout debugging’ ubersetzen sie den Quell-Code und starten ihre erste Dialog- ¨Applikation (Fig. 12.37). Abbildung 12.37: Die leere Dialog-Anwendung
    • 138 KAPITEL 12 SOFTWARE-INSTALLATION12.6 .NET FormularMit dem MSDS (Micro-Soft Developer Studio) 2005 braucht man genau 5Mausklicks, um eine Dialog-Anwendung zu erstellen (siehe Anlage 12.5), mitder 2008er Version sind es nur noch 3 f¨ r ein sogenanntes Formular (die Weiter- uentwicklung von Dialogen). Wir schauen uns jetzt die Erzeugung der Formular-Applikation mit VC++2008 an, machen aber dann in Abschn. 10.1 mit derDialog-Anwendung weiter. Abbildung 12.38: Starten von VC++2008
    • 12.6 .NET FORMULAR 139Nach dem Starten von VC++ (Fig. 12.38) m¨ ssen wir ein neues Projekt anlegen u(Fig. 12.39). Abbildung 12.39: Klick 1: Neues Projekt anlegen Abbildung 12.40: Klick 2: Windows Form-AnwendungW¨hlen sie ’CLR’ (Erkl¨rung folgt) → ’Windows Form-Anwendung’ aus. ’Win- a a
    • 140 KAPITEL 12 SOFTWARE-INSTALLATIONdows Forms’ sind die neue Form von ’Windows Dialogen’. W¨hlen Sie im unteren aTeil des Dialogs (Fig. 12.40) das Verzeichnis f¨ r ihr Dialog-Projekt und geben usie ihm einen Namen. Der ’Projektgruppen-Name’ wird automatisch vergeben.In dem Moment, wenn sie ’OK’ dr¨ cken (Klick 3), wird der gesamte Quell-Code uf¨ r ihre Dialog-Anwendung erzeugt. Mit ’Ctrl-F5’ oder Debug → ’Start without udebugging’ ubersetzen sie den Quell-Code (Fig. 12.41) und starten ihre erste ¨Dialog-Applikation (Fig. 12.42). ¨ Abbildung 12.41: ’Ctrl-F5’: Ubersetzen und starten des Dialogs Abbildung 12.42: Eine ’leere’ Windows Formular-Anwendung
    • 12.7 UBUNTU & WINE 14112.7 UBUNTU & WineMan kann Windows-Applikationen unter UBUNTU starten. Dazu muss das Pro-gramm ’Wine’ installiert werden. Hier kommt eine kurze Installationsanleitung.F¨ r den Download und die Installation von Wine Microsoft Windows Com- upatibility Layer ben¨tigen sie nat¨ rlich eine Internetverbindung. Gehen sie zu o uAnwendungen > Hinzuf¨ gen/Entfernen > Suche: Wine. u Abbildung 12.43: Anwendung Wine hinzuf¨ gen uNun werden die Paketdateien f¨ r Wine heruntergeladen. u Abbildung 12.44: Paketdateien f¨ r Wine werden heruntergeladen uDanach werden die Software-Pakete f¨ r Wine installiert. u
    • 142 KAPITEL 12 SOFTWARE-INSTALLATION. Abbildung 12.45: Installation der Software-PaketeZur Ausf¨ hrung der Windows exe Datei gehen sie wie folgt vor: Rechtsklick auf uDatei > Mit >>Wine Windows-Programmstarter<< ¨ffnen, die Anwendung owird nun wie unter Windows ausgef¨hrt. uInstallierte Programme werden in einem Windows nachempfundenen Verzeich-nissystem installiert z.B. home/user/.wine/dosdevices/c: sowiehome/user/.wine/dosdevices/c:/Programme. Installierte Programme/Anwendun-gen k¨nnen unter Anwendungen > Wine > Programme bzw. Durchsuche C: ogefunden werden.
    • 12.8 QT INSTALLATION 14312.8 Qt InstallationQt installation
    • 144 KAPITEL 12 SOFTWARE-INSTALLATIONZur Qt Installation gehen sie auf folgende Web-Seite und folgen den Schrittengem¨ß den Abbildungen: http://www.qtsoftware.com/products/. W¨hlen die a afreie LGPL Lizenz.Dabei wird die Installationsdatei f¨ r das entsprechende Betriebssystem herun- utergeladen (Abb. 12.46). Abbildung 12.46: Qt Installationsdatei f¨ r Windows uNach der Installation haben sie den Qt Creator zur Verf¨ gung (Abb. 12.47). u Abbildung 12.47: Qt Creator
    • Kapitel 13Students ForumVielen Dank f¨ r Ihre Fragen zur ersten Vorlesung! u13.1 Vorlesung 1: 17.04.2009JB Der C compiler funktioniert, der C++ aber nicht: Wahrscheinlich haben sie nur den C Compiler (GCC) installiert. Die k¨nnen jederzeit cygwin o Komponenten nachinstallieren , siehe Abschn. 12.2.2.2. ¨DB Ich habe den MS VC++ installiert und kann die Ubungen nachvollziehen. Brauche ich den GNU Compiler von cygwin wirklich noch ?: Eigentlich nicht, mit MS VC++ haben sie einen kompletten Compiler mit allem drum und dran, dennoch kann ein Ausflug in die Konsolenwelt ja nicht schaden ... und sie k¨nnen sp¨ter in ihre Bewerbungen schreiben, dass sie o a auch unter Linux Programme entwickelt haben.MF Die aktuelle cygwin Installation sieht anders aus als im Skript beschrieben: [OK] Im Anhang (Abschn. 12.2.2.2) finden sie eine bessere Beschreibung der cygwin Installation. C++ und Mac: erstmal eine Adresse http://developer.apple.com/TOOLS/xcode/ 145
    • Kapitel 14Questions14.1 Testfragen - Kapitel 1 - Einfuhrung ¨ 1. Was bedeutet das ++ im Namen der Programmiersprache C++ ? 2. Ist C++ eine standardisierte Programmiersprache ? 3. Was ist der Unterschied zwischen C und C++ ? 4. Was sind sogenannte Programmier-Paradigmen ? 5. Welche verschiedenen Programmier-Paradigmen kennen sie und worin un- terscheiden sie sich ? 6. Welches Paradigma verfolgen wir in der Vorlesung ? 7. Was ist objekt-orientierte Programmierung ? 8. Was ist ein Kompiler ? 9. Erkl¨ren sie die einzelnen Schritte bei einer Kompilierung (s. Abb. 1.4). a ¨ 10. Welchen Kompiler benutzen sie f¨ r die C++ Ubungen ? u 11. Welche Funktion ben¨tigt jedes C oder C++ Programm ? o 12. Was ist der Typ einer Funktion ? 13. Was ist eine Parameterliste einer Funktion ? 14. Was ist der R¨ ckgabewert einer Funktion ? u 146
    • 14.2 TESTFRAGEN - KAPITEL 2 - DATENTYPEN 14714.2 Testfragen - Kapitel 2 - Datentypen 1. Was ist der genaueste Datentyp in C++ ? 2. Wie groß ist der Speicherbedarf von einem string Datentyp ? 3. Mit welcher Anweisung k¨nnen wir den Speicherbedarf von elementaren o Datentypen ermitteln ? 4. Was sind Escape-Sequenzen ? 5. Was ist der Unterschied zwischen den Escape-Sequenzen n und r ? 6. Was ist die C++ Entsprechung der Klasse cout f¨ r einen Zeilenumbruch u ?14.3 Testfragen - Kapitel 3 - Ein- und Ausgabe I 1. Sind sie mit der Tab. 2.2 einverstanden ? 2. Welche Ein- und Ausgabeger¨te kennen sie ? a 3. Welche Klasse ben¨tigen wir f¨ r die Standard-Ein- und Ausgabe ? o u 4. Was ist die Basis-Klasse f¨ r alle Ein- und Ausgaben in C++ ? u 5. Mit welcher Klasse k¨nnen wir sowohl Eingabe- als auch Ausgabestr¨me o o benutzen ? 6. Welche Include-Datei ist notwendig, um mit I/O-Str¨men arbeiten zu o k¨nnen ? o 7. Wozu dient der Zusatz using namespace std; nach dem Include von Standard-Klassen, wie I/O Streams ? 8. Was bewirken die Stream-Operatoren << und >> ? 9. Was bewirken die Flags oct, dec, hex f¨ r die formatierte Ausgabe von u Ganzzahlen ? (ToDo) 10. Wie kann ich die Genauigkeit der Ausgabe von Gleikomma-Zahlen festle- gen ? 11. Wie kann man den Speicherbedarf einer Variable ermitteln ? Schreiben sie die C++ Anweisung f¨ r die Berechnung des Speicherbedarfs f¨ r eine u u doppelt-genaue Gleitkomma-Zahl.
    • 148 KAPITEL 14 QUESTIONS14.4 Testfragen - Kapitel 4 - Klassen 1. Geben sie eine Definition von C++ Klassen mit eigenen Worten (max 5 S¨tze). a 2. Was ist ein benutzerdefinierter Datentyp ? 3. Welches Datennschutz-Konzept gibt es f¨ r Klassen ? u 4. Wozu brauchen wir zwei Dateien f¨ r Klassen, eine H (Header) Datei und u eine CPP (Quelltext) Datei ? 5. Was ist ein Inklude / Include ? 6. Was ist eine Instanz einer Klasse ? 7. Worin besteht der Unterschied zwischen den Anweisungen: CStudent m std 1 und CStudent* m std 2 ? 8. Was ist ein Konstruktor einer Klasse ? 9. Was ist das Gegenst¨ ck zum Klassen-Konstruktor ? u 10. Wie k¨nnen Daten / Variablen einer Klasse initialisiert werden ? o 11. Schreiben sie den Quelltext f¨ r den Klassen-Konstruktor und weisen sie u den Variablen name first und name last ihren eigenen Namen zu. 12. Was verbirgt sich hinter der Anweisung: CStudent* m std = new CStudent() ? 13. Was ist der Unterschied zwischen CStudent und CStudent() ? 14. Wie kann ich meine Daten gegen einen externen Zugriff sch¨ tzen ? u14.5 Testfragen - Kapitel 5 - Strings 1. Welche Klasse bietet uns C++ zur Verarbeitung von Zeichenketten an ? 2. Welchen Include ben¨tigen wir f¨ r die Arbeit mit Zeichenketten ? o u 3. Wof¨ r ist die Anweisung using namespace std n¨ tzlich ? u u 4. M¨ ssen wir selber Speicherplatz f¨ r C++ Zeichenketten (Strings) reser- u u vieren ? 5. Wie k¨nnen wir einen String, sagen wir mit der Zeichenkette ”Das ist eine o gute Frage”, initialisieren ? 6. Wie k¨nnen wir zwei Strings, ihren Vor- und Nachnahmen, miteinander o verbinden ?
    • 14.6 TESTFRAGEN - KAPITEL 6 - EIN- UND AUSGABE II 149 7. Mit welcher string Funktion kann ich Zeichenketten miteinander verglei- chen ? 8. Schreiben sie eine Anweisung zum Vergleich der Klassen-Variable m std− >name last mit ihrem Nachnamen ? 9. Mit welcher string Funktion kann ich Zeichenketten suchen ? 10. Schreiben sie eine Anweisung zum Suchen ihres Vornamens in der Klassen- Variable m std− >name first ? 11. Mit welcher string Funktion kann ich Teile in Zeichenketten erstetzen ? 12. Wie k¨nnen wir die L¨nge von Strings ermitteln ? o a 13. Schreiben sie die Anweisungen, um ihren Nachnamen in die Zeichenkette ”JAMES BOND” nach ”JAMES” einzuf¨ gen ?u 14. Was passiert, wenn ihr Nachname l¨nger als ”BOND” ist ? a 15. Mit welcher string Funktion k¨nnen wir Zeichen in einem String l¨schen ? o o 16. Wir haben gesehen, dass es verschiedene Daten-Typen f¨ r Zeichenketten u in C, C++, MFC, .NET und Qt gibt. Zeichenketten geh¨ren zu den wich- o tigsten Daten-Typen bei der Programmierung. Wie k¨nnen wir einen C++ o string in eine C Zeichenkette (char) umwandeln ? 17. K¨nnen wir eine .NET Zeichenkette (String∧) in eine C++ Zeichenkette o (string) umwandeln ? 18. Was ist ein stringstream ? 19. Welchen Include ben¨tigen wir f¨ r die Arbeit mit Stringstreams ? o u14.6 Testfragen - Kapitel 6 - Ein- und Ausgabe II 1. Was ist die Basis-Klasse f¨ r alle Ein- und Ausgaben in C++ ? u 2. Was sind die C++ Klassen f¨ r das Lesen und Schreiben von Dateien ? u 3. Welchen Include ben¨tigen wir f¨ r das Arbeiten mit I/O File-Klassen ? o u 4. Was sind die Standard-Flags f¨ r File-Streams (Lesen und Schreiben) ? u 5. Mit welchem Flag k¨nnen wir zu schreibende Daten an eine existierende o Datei anh¨ngen ? a 6. Was ist der Unterschied zwischen ASCII- und Bin¨r-Formaten ? a
    • 150 KAPITEL 14 QUESTIONS 7. Mit welchem Flag k¨nnen wir Daten in einem Bin¨r-Format schreiben ? o a Mit welcher Anweisung wird ein File ge¨ffnet ? Mit welcher Anweisung o wird ein File geschlossen ? 8. Was bewirken die Stream-Operatoren << und >> ? 9. Wie k¨nnen wir mit Dateinamen in unserem Hauptprogramm main(...) o arbeiten ? 10. Welche Anweisung ben¨tigen wir f¨ r die Erzeugung einer Instanz f¨ r einen o u u Eingabe-Strom ? 11. Welche Anweisung ben¨tigen wir f¨ r die Erzeugung einer Instanz f¨ r einen o u u Ausgabe-Strom ? 12. F¨ r die Erstellung einer Datenbank ist es wichtig einzelnen Datens¨tze zu u a trennen. Wie k¨nnen wir soetwas in der Datenbank-Datei bewerkstelligen o ? 13. Ist es wichtig das Ende einer Datenbank-Datei, z.B. mit einem Schl¨ ssel- u wort #STOP, zu markieren ? o u ¨ 14. Mit welcher Abfrage k¨nne wir pr¨ fen, ob die Offnung einer Datei erfolg- reich war ? 15. Mit welcher Anweisung k¨nnen wir die aktuell gelesene Position in einer o ge¨ffneten Datei abfragen ? o 16. Mit welcher Anweisung k¨nnen wir zu einer bestimmten Position in einer o ge¨ffneten Datei springen ? o 17. Mit welcher Anweisung k¨nnen wir eine komplette Zeile aus ge¨ffneten o o Datei auslesen ?14.7 Testfragen - Kapitel 7 - Referenzen und Zeiger 1. Was ist &x ? (x ist ein beliebiger Datenobjekt T, z.B. eine Gleitkomma- zahl: double x) 2. Was ist eine Referenz &ref? 3. Was bedeutet die Anweisung: &ref = x? 4. Erkl¨ren sie kurz (mit eigenen Worten) das Zeiger-Konzept in C++? a 5. Was bewirkt der NULL Zeiger, d.h. *ptr = NULL ? 6. Was bedeutet die Anweisung: ptr = x?
    • 14.8 TESTFRAGEN - KAPITEL 8 - CONTAINER 151 7. M¨ ssen Referenzen (&) und Zeiger (*) auf Daten-Objekte initialisiert wer- u den ? 8. Was bewirkt die Definition long l[1000] speichertechnisch ? 9. Wie groß ist der Speicherbedarf des statischen Datenobjekts long l[1000] ? 10. Wie groß ist der Speicherbedarf des dynamische Datenobjekts long* ptr l = new long[1000] ? 11. Woher kommt der Unterschied (4 Byte auf einem 32Bit Rechner) im Speicherbedarf zwischen statischen und dynamischen Datenobjekten. 12. Zusatzfrage: Was bedeutet die Definition **ptrptr (Zeiger auf Zeiger), was f¨ r ein Datenkonstrukt entsteht ? u14.8 Testfragen - Kapitel 8 - Container 1. Was sind C++ Container ? 2. Welche Typen von C++ Containern kennen sie ? 3. Worin besteht der Unterschied zwischen sequentiellen und assoziativen Containern ? 4. Welche sequentiellen Container kennen sie ? 5. Erkl¨ren sie die Syntax des Vektor-Containers: vector<int>my vector . a 6. Was ist der Unterschied zwischen Vektoren und Listen ? 7. Was sind die Gemeinsamkeiten von Vektoren und Listen ? 8. Welcher Include ist notwendig f¨ r das Arbeiten mit Vektoren ? u 9. Welcher Include ist notwendig f¨ r das Arbeiten mit Listen ? u 10. Ben¨tigen wir den Zusatz (Namensraum) using namespace std, wenn ja o warum ? 11. Mit welcher Instruktion k¨nnen Elemente in Vektoren und Listen einf¨ gen o u ? 12. Wo werden sequentielle Container-Elemente mit der Instruktion push back(T) eingef¨ gt ? u 13. Mit welcher Anweisung k¨nnen wir die L¨nge von sequentiellen Container- o a Elementen bestimmen ?
    • 152 KAPITEL 14 QUESTIONS 14. Mit welcher Anweisung k¨nnen wir einen Vektor platt machen (d.h. alle o Elemente l¨schen) ? o 15. Wie k¨nnen wir auf ein Vektor-Element, sagen wir das 17te Element des o Vektors vector<int>my vector, direkt zugreifen ? 16. Quellcode verstehen: Erkl¨ren sie die Struktur (1,2,3) der DB-Lese-Funktion a ¨ STDRead(ifstream& std file) in der Ubung 8.2.2. Beginnen sie mit der Pa- rameterliste. 17. Wie k¨nnen wir unsere Studenten-Klasse CStudent in die DB-Anwendung o ¨ (Ubung 8.2.1) einbinden ? u a ¨ 18. Was ist eigentliche Lesefunktion f¨ r unsere Studenten-Datens¨tze (Ubung 8.2.2) ? 19. Mit welchem Befehl k¨nnen wir die Reihenfolge von Listen-Elementen o umkehren ? 20. K¨nnen wir Listen-Elemente sortieren, wenn ja wie, mit welcher Instruk- o tion ? 21. Mit welchem Befehl k¨nnen wir mehrere Listen zusammenf¨ hren ? o u 22. K¨nnen wir doppelte Elemente aus einer Liste entfernen sortieren, wenn o ja wie, mit welcher Instruktion ? 23. Was ist ein Iterator ? 24. Quellcode verstehen: Erkl¨ren sie die Funktion void display(list<int>my list) a ¨ der Ubung 8.3. Beginnen sie mit der Parameterliste. 25. Wie k¨nnen wir Elemente aus einer Liste entfernen ? o14.9 Testfragen - Kapitel 9 - Andere Sprachele- mente 1. Was sind Kontrollstrukturen, welche kennen sie ? 2. Bei welcher logischen Bedingung wird eine if-Anweisung ausgef¨ hrt ? u 3. Lassen sich Kontroll-Strukturen verschachteln ? 4. Mit welcher Kontrollstruktur k¨nnen wir Fallunterscheidungen program- o mieren ? 5. Welche Ausdr¨ cke k¨nnen wir bei der switch-case Kontrollstruktur be- u o nutzen ? 6. Wie kann ich eine Kompiler-Direktive an- und ausschalten ?
    • 14.10 TESTFRAGEN - KAPITEL 10 - DIALOGE 153 ¨ 7. Schreiben sie die Ubung 9.2.2.2 f¨ r die Benutzung von #ifndef anstelle u von #ifdef um. 8. Erl¨utern sie den Kopf der for-Schleife: for(int i=0;i<stop;i++), wel- a chen Daten-Typ hat stop ? 9. Was ist eine Endlos-Schleife, wie kommen wir daraus ? 10. Was sind Namensbereiche ? 11. Was m¨ ssen wir tun, um die Arbeit mit C++ Standard-Klassen zu verein- u fachen, d.h anstelle von std::my string() direkt my string() benutzen zu k¨nnen ? o 12. Was sind Kompiler-Direktiven, was bewirken diese ? 13. Wie k¨nnen wir Kompiler-Direktiven an- und ausschalten ? o 14. Worin besteht der Unterschied bei Includes mit eckigen Klammern < ... > bzw. mit G¨nsef¨ ßchen ”...” ? a u ¨ 15. Schreiben sie die Ubung 9.2.2.2 f¨ r die Benutzung von #ifndef anstelle u von #ifdef um ? 16. Was sind Makros ? 17. Welche beiden Einsatzm¨glickeiten von Makros gibt es ? o 18. Worin besteht die Gefahr, Makros als Funktionsersatz zu benutzen ?14.10 Testfragen - Kapitel 10 - DialogeMFC 1. Welche Typen von grafischen Windows-Applikationen kennen sie ? 2. Was ist eine Dialog-Resource ? 3. Welche Dialog-Elemente haben wir in unserer Windows-Applikation be- nutzt (Abb. 10.3) ? 4. Was sind IDs ? 5. Was ist eine MESSAGE MAP ? 6. Wie wird die Verbindung zwischen Funktionen und grafischen Dialog- Elementen hergestellt ? 7. Wie wird die Verbindung zwischen Daten und grafischen Dialog-Elementen hergestellt ?
    • 154 KAPITEL 14 QUESTIONS 8. Was bedeutet die Definition: class CMyDialog : public CDialog ? 9. Wie wird ein Dialog aufgerufen (Funktion der Klasse CDialog)? 10. Was bewirkt die Dialog-Funktion UpdateData() ? 11. Was ist die Schnittstelle zwischen dem Dialog und unserer Studenten- Klasse ? 12. Wie kann ich Files unter Windows ¨ffnen (welche Klasse) ? o 13. Was ist ein BMP ?.NET 1. Was ist eine Formular-Resource ? 2. Welche Formular-Elemente haben wir in unserer .NET-Applikation be- nutzt (Abb. 10.10) ? 3. Wie wird die Verbindung zwischen Funktionen und grafischen Formular- Elementen hergestellt ? 4. Wie wird die Verbindung zwischen Daten und grafischen Formular-Elementen hergestellt ? 5. Was bedeutet die Definition: private: System::Windows::Forms::Button MyButton ? 6. Was bedeutet die Definition: private: System::Void button3 Click() ? 7. Wie wird ein Formular aufgerufen (Funktion der Klasse Form1)? 8. Was ist die Schnittstelle zwischen dem Dialog und unserer Studenten- Klasse ? 9. Wie kann ich Files mit .NET ¨ffnen (welche Klasse) ? o= 158.
    • Literaturverzeichnis[1] Stroustrup B. The programming languages C++. Addison-Wesley, Reading, 1991.[2] Blanchette J and Summerfield M. C++ GUI Programming with Qt 4. Pren- tice Hall, Boston, 2006.[3] Kolditz O. Computational methods in environmental fluid mechanics. Sprin- ger, Berlin-Heidelberg, 2002.[4] Breymann U. C++ Einf¨hrung und professionelle Programmierung. Hanser, u M¨ nchen-Wien, 2001. u[5] Kirch-Prinz U and Prinz P. C++ Lernen und professionell anwenden. mitp, Heidelberg, 2007. 155
    • InhaltsverzeichnisPart I - C++ Basics 61 Einf¨hrung u 7 1.1 Historisches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 1.2 Paradigmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.3 Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.3.1 GNU . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.3.2 MS Visual C++ . . . . . . . . . . . . . . . . . . . . . . . 13 1.3.3 Qt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 1.4 ”Hello World” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.4.1 Grundlagen . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.4.2 Exercise E1 . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.5 Students Forum . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.6 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172 Datentypen 18 2.1 Elementare Datentypen . . . . . . . . . . . . . . . . . . . . . . . 18 2.2 Speicherbedarf . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.3 Escape-Sequenzen . . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.4 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203 Ein- und Ausgabe 21 3.1 Die Standard-Streams . . . . . . . . . . . . . . . . . . . . . . . . 23 3.2 Formatierte Ausgaben . . . . . . . . . . . . . . . . . . . . . . . . 23 3.2.1 Formatierte Ausgabe von Ganzzahlen . . . . . . . . . . . 23 156
    • INHALTSVERZEICHNIS 157 3.2.2 Formatierte Ausgabe von Gleitpunktzahlen . . . . . . . . 24 3.2.3 Ausgabe von Speicherbedarf . . . . . . . . . . . . . . . . . 24 3.3 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254 Klassen 26 4.1 Daten-Abstraktion . . . . . . . . . . . . . . . . . . . . . . . . . . 27 4.2 Klassen-Deklaration . . . . . . . . . . . . . . . . . . . . . . . . . 28 4.3 Instanzen einer Klasse . . . . . . . . . . . . . . . . . . . . . . . . 28 4.4 Konstruktor und Destruktor . . . . . . . . . . . . . . . . . . . . . 30 4.5 Dateninitialisierung mit dem Konstruktor . . . . . . . . . . . . . 31 4.6 Datenschutz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 4.7 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 345 Strings 35 5.1 Die Standardklasse string . . . . . . . . . . . . . . . . . . . . . . 35 5.2 Operationen mit strings . . . . . . . . . . . . . . . . . . . . . . . 36 5.2.1 Initialisieren von strings . . . . . . . . . . . . . . . . . . . 36 5.2.2 Zuweisen von strings . . . . . . . . . . . . . . . . . . . . . 37 5.2.3 Verketten von strings . . . . . . . . . . . . . . . . . . . . 37 5.2.4 Vergleichen von strings . . . . . . . . . . . . . . . . . . . . 37 5.2.5 Suchen in strings . . . . . . . . . . . . . . . . . . . . . . . 38 5.2.6 Einf¨ gen in strings . . . . . . . . . . . . . . . . . . . . . . u 38 5.2.7 Ersetzen in strings . . . . . . . . . . . . . . . . . . . . . . 39 5.2.8 L¨schen in strings . . . . . . . . . . . . . . . . . . . . . . o 39 5.2.9 Umwandeln von strings in char . . . . . . . . . . . . . . . 40 5.2.10 Auswerten von Strings: Stringstreams . . . . . . . . . . . 40 5.3 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416 Ein- und Ausgabe - II 42 6.1 Die fstream Klassen . . . . . . . . . . . . . . . . . . . . . . . . . 42 6.2 Arbeiten mit File-Streams . . . . . . . . . . . . . . . . . . . . . . 43 6.2.1 File-Streams anlegen . . . . . . . . . . . . . . . . . . . . . 43 6.2.2 File-Streams schließen . . . . . . . . . . . . . . . . . . . . 43 6.2.3 ¨ Ubung: Eine einfache Kopierfunktion . . . . . . . . . . . . 43
    • 158 INHALTSVERZEICHNIS 6.2.4 ¨ Ubung: Ein einfacher Konverter . . . . . . . . . . . . . . . 45 6.2.5 Einschub: Erstes Arbeiten mit MS VC++ . . . . . . . . . 46 6.3 File-Streams und Klassen . . . . . . . . . . . . . . . . . . . . . . 49 6.4 fstream Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . 52 6.5 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537 Referenzen und Zeiger 54 7.1 Referenzen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 7.1.1 Das Call-by-reference Prinzip - Referenzen als Parameter 55 7.1.2 Referenzen als R¨ ckgabe-Wert . . . . . . . . . . . . . . . u 56 7.2 Zeiger . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 7.2.1 Definition von Zeigern . . . . . . . . . . . . . . . . . . . . 57 7.2.2 NULL Zeiger . . . . . . . . . . . . . . . . . . . . . . . . . 57 7.2.3 Zeiger als Parameter . . . . . . . . . . . . . . . . . . . . . 58 7.3 Zeiger und Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . 58 7.3.1 Statische Objekte . . . . . . . . . . . . . . . . . . . . . . . 58 7.3.2 Dynamische Objekte . . . . . . . . . . . . . . . . . . . . . 58 7.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59 7.5 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618 Container 62 8.1 Sequentielle Container . . . . . . . . . . . . . . . . . . . . . . . . 63 8.2 Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 8.2.1 Defining vectors . . . . . . . . . . . . . . . . . . . . . . . 66 8.2.2 Vectors and data base . . . . . . . . . . . . . . . . . . . . 66 8.2.3 Updating your data base entry . . . . . . . . . . . . . . . 68 8.3 Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69 8.4 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 719 Andere Sprachelemente 73 9.1 Kontrollstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . . 73 9.1.1 if-else . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 9.1.2 switch-case . . . . . . . . . . . . . . . . . . . . . . . . . 74 9.1.3 for . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
    • INHALTSVERZEICHNIS 159 9.1.4 while . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 9.1.5 continue, break, return . . . . . . . . . . . . . . . . . 75 9.2 G¨ ltigkeitsbereiche . . . . . . . . . . . . . . . . . . . . . . . . . . u 76 9.2.1 Namensbereiche . . . . . . . . . . . . . . . . . . . . . . . 76 9.2.2 Compiler-Direktiven – # . . . . . . . . . . . . . . . . . . 76 9.3 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78Part II - Visual C++ 8010 Dialoge 82 10.1 What have we (i.e. MFC) created ? . . . . . . . . . . . . . . . . . 82 10.2 Gestaltung des Dialogs . . . . . . . . . . . . . . . . . . . . . . . . 85 10.3 Programmierung des Dialogs – MyDialogDlg . . . . . . . . . . . 87 10.3.1 Dialog-Funktionen . . . . . . . . . . . . . . . . . . . . . . 87 10.3.2 Dialog-Daten . . . . . . . . . . . . . . . . . . . . . . . . . 87 10.3.3 Implementierung des Dialogs . . . . . . . . . . . . . . . . 88 10.3.4 Schnittstelle zwischen Dialog- und Studenten-Klasse . . . 89 10.3.5 N¨ tzliche Windows-Funktionen . . . . . . . . . . . . . . . u 92 10.4 Das .NET Formular . . . . . . . . . . . . . . . . . . . . . . . . . 94 10.4.1 Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . 95 10.4.2 Daten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 ¨ 10.4.3 Ubung: Hinzuf¨ gen von Funktionen . . . . . . . . . . . . u 97 10.5 HomeWorks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 10.6 Testfragen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10211 Qt 104 11.1 Hello Qt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 11.2 Executable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 11.3 Quit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106 11.4 Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107Part III - Anlagen / Software 111
    • 12 Software-Installation 112 12.1 cygwin Installation . . . . . . . . . . . . . . . . . . . . . . . . . . 113 12.2 LINUX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 ¨ 12.2.1 Ubersicht einiger grundlegenden Linux-Befehle . . . . . . 122 12.2.2 Profile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 12.2.3 Make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 12.3 Sch¨ sselworte in C++ . . . . . . . . . . . . . . . . . . . . . . . . 129 u 12.4 MS VC++ Projekt #1 - Eine Konsolenanwendung . . . . . . . . 130 12.5 MFC-Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134 12.6 .NET Formular . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138 12.7 UBUNTU & Wine . . . . . . . . . . . . . . . . . . . . . . . . . . 141 12.8 Qt Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14313 Students Forum 145 13.1 Vorlesung 1: 17.04.2009 . . . . . . . . . . . . . . . . . . . . . . . 14514 Questions 146 14.1 Testfragen - Kapitel 1 - Einf¨ hrung . . . . . . . . . . . . . . . . . 146 u 14.2 Testfragen - Kapitel 2 - Datentypen . . . . . . . . . . . . . . . . 147 14.3 Testfragen - Kapitel 3 - Ein- und Ausgabe I . . . . . . . . . . . . 147 14.4 Testfragen - Kapitel 4 - Klassen . . . . . . . . . . . . . . . . . . . 148 14.5 Testfragen - Kapitel 5 - Strings . . . . . . . . . . . . . . . . . . . 148 14.6 Testfragen - Kapitel 6 - Ein- und Ausgabe II . . . . . . . . . . . 149 14.7 Testfragen - Kapitel 7 - Referenzen und Zeiger . . . . . . . . . . 150 14.8 Testfragen - Kapitel 8 - Container . . . . . . . . . . . . . . . . . 151 14.9 Testfragen - Kapitel 9 - Andere Sprachelemente . . . . . . . . . . 152 14.10Testfragen - Kapitel 10 - Dialoge . . . . . . . . . . . . . . . . . . 153