Table Of ContentProgrammieren
in C++
Borland-Versionen
Ein Lehr- und Obungsbuch
Von Prof. Henning Mittelbach
Fachhochschule MOnchen
83
B. G. Teubner Stuttgart 1998
Aile im vorliegenden Buch erwahnten Produkt- und Firmennamen wie Borland,
Hewlett Packard, IBM, MS. DOS, Turbo Pascal u. a. sind gesetzlich geschOtzt, ohne
daB im einzelnen darauf hingewiesen wird.
Die Deutsche Bibliothek - CIP-Einheitsaufnahme
Mittelbach, Henning:
Programmieren in C++, Borland-Versionen : ein Lehr-und
Obungsbuch / von Henning Mittelbach. - Stuttgart: Teubner, 1998
ISBN-13:978-3-519-02998-4 e-ISBN-13:978-3-322-80112-8
DOl: 10.1007/978-3-322-80112-8
Das Werk einschlieBlich aller seiner Teile ist urheberrechtlich geschOtzt. Jede Verwer
tung auBerhalb der engen Grenzen des Urheberrechtsgesetzes ist ohne Zustimmung
des Verlages unzulassig und strafbar. Das gilt besonders fOr Vervielfaltigungen,
Obersetzungen, Mikroverfilmungen und die Einspeicherung und Verarbeitung in
elektronischen Systemen
© B. G. Teubner Stuttgart 1998
Zu diesem Buch
Der vorliegende Text will kein systematisches Lehrbuch in C++ sein und hat auch
keinen Anspruch auf Vollstandigkeit der Darstellung. Die Intention ist eher folgende:
Wer bisher mit einer ,,klassischen" Sprache wie Pascal ,,gelebt" hat, soIl in moglichst
kurzer Zeit und ohne allzu groBe Millie befahigt werden, Programme in c++ zu Ie sen,
zu verandem und bei "defensivem" Sprachgebrauch einfachere Listings auch bald zu
schreiben. Wer meine zu Turbo Pascal erschienenen Bucher kennt, wird die etwas
unubliche Darstellung von dort sofort wiedererkennen:
Mit nicht-trivialen Beispielen dringt man schnell in die Materie ein und ist bald in der
Lage, offene Fragen durch eigene Experimente in der IDE oder durch Nachlesen in
Monographien zu klaren. Das folgende Manuskript reHektiert meinen eigenen Weg,
von Pascal ausgehend in die Hohen und auch Tiefen von C++ vorzudringen. Es ist das
Protokoll eines intensiven Lemvorgangs, der ungefahr drei Monate dauerte und nicht
immer das reine Vergnugen war. Konkrete Einzelfragen konnten die von mir zu Rate
gezogenen Lehrbucher nicht immer beantworten: Sie hielten sich in erster Linie mit
syntaktischen Uberlegungen und Theorie auf, zeigten aber weniger, "wie es geht". Erst
nachdem ich das seIber herausgefunden hatte, fing ich damit an, mich eingehend mit
Details zur Syntax zu befassen, mit dem "Warum": Jetzt kam bei mir die ,,Konkurrenz"
zum Zuge: Die recht subjektive Auswahl an entsprechender Literatur ist in einer
Ubersicht zusammengestellt.
Nach der ersten Rohfassung des ManuskIipts gab es einen Testdurchlauf in einer
Anfiingervorlesung, und damit Kritik und Verbesserungsvorschlage in Hiille und Fulle.
Bei der anschlieBenden Uberarbeitung habe ich auch an solche Leserinnen und Leser
gedacht, die ohne Vorkenntnisse aus einer anderen Sprache in die Fan-Gemeinde C++
eingebiirgert werden wollen. Eine Menge eher allgemeiner Hinweise zur Programmier
umgebung, zu Beispielalgorithmen usw. war zwangslaufig die Folge; insb. kamen die
Kapitel 3 und 9 bis 11, zwei Aufgabenteile und ein kleines Glossar hinzu.
In den ersten elf Kapiteln geht es hauptsachlich um element are Datentypen, Kontroll
strukturen und den Funktionsbegriff; OOP-Eigenschaften von C++ als Uberbau von C
treten noch nicht in Erscheinung. Die Beispiele sind so gewiihlt, daB recht viele ver
schiedene Anweisungen und Algoritlunen auftauchen. Man gewinnt dabei so viel
Durchblick, daB dann die meisten Aufgaben ohne weiteres ,,klassisch" gelost werden
konnen. Wer eine andere imperative Sprache beherrscht, sollte diesen Teil mit
maBigem AufWand durcharbeiten konnel1 wld sehr schnell in die Lage versetzt werden,
auch komplexere Algorithmen zuverlassig in C++ zu schreiben, z.B. Quellfiles aus
Pascal zu "ubersetzen". Das StichwOltverzeichnis erleichtert diesen Zugang.
4
Ab Kapitel12 wird das OOP-Paradigma von C++ deutlich. Jetzt wird es zumindest fUr
Programmieranfanger einigennafien schwierig. Begriffe wie Klassen, Methoden, Ver
erbung und Hierarchie werden erortert und an umfangreicheren Beispielen lauffahig
vorgefiihrt. Wer die OOP-Philosophie von Turbo Pascal kennt, wird dabei allerhand
Ahnlichkeiten erkennen. Dieser Teil des Buches wird sicherlich erst nach etlichen
Wochen des Lemens und Ubens dazu fiihren, dafi (je nach Vorkenntnissen) ein
efl'ektiver Einsatz des nach und nach Gelernten moglich wird. ,,Learning by doing" ist
die beste Vorgehensweise. Mit den elworbenen Grundkenntnissen sollte es danach
moglich sein, auf eigene Faust in die Geheimnisse von OOP anhand weiterer Literatur
tiefer einzudringen: Die OOP -Kapitel sind als Einfiihrung zu verstehen.
Ich denke, dafi dieses Buch auch von echten Anflingern durchgearbeitet werden kann,
sofem sie deutlich mehr Millie als Quereinsteiger auf sich nehmen wollen und die
Energie mitbringen, Algorithmen zu hinterfragen, die ohne ausfiihrliche Erlauterung
einfach "vorgesetzt" werden: SOltieren, Iteration, Rekursion, ... : Dies und anderes
wird praktisch vorgefiihrt und meist nur kurz begriindet; zu komplexeren Algorithmen
gibt es aber hie und da doch Struktogramme oder grafische Erlauterungen.
Viele Beispiele sind mathematisch orientiert und bedurfen daher einiger Hintergrund
kenntnisse, auf die das Buch mangels Umfang oft nur am Rande eingehen kann. FUr
Studierende der Ingenieutwissenschaften und engagierte Oberstufenschiller (sowie
deren Lehrer) sollte das aber keill Problem sein: Vor allem an diese Gruppen wendet
sich der Text, aber ebenso an engagielte Hobbyprogrammierer. Wer sich fehlende
Infonnationen mit Sprachmustern aus Pascal verschafl'en mochte, sei auf meine beiden
Bucher [M] verwiesen. Diese werden hie und da zitiert; aber man mnfi sie weder
besitzen, noch gar gelesen haben! - Zuletzt: AIle Files aus diesem Buch gibt es auch
auf einer Diskette; niiheres nach der Literaturliste.
Ein DankeschOn gilt meinem Anfallgerkurs an der FH Miinchen im SS 1997, der mit
den Texten testhalber konfrontielt worden ist, so manchen sachlichen Fehler fand und
auch allerhand Verbesserungsvorschliige einbrachte. Auf reine Schreibfehler (vor dem
Hintergrund der "alten" Orthografie) wurde dabei weniger geachtet: Solche Fehler
(und erst recht alle fachlichen) gehen vollstiindig zu meinen Lasten. Besonderer Dank
schliefilich an Herm Dr. Spuhler von der Verlagsleitung Teubner fUr die bereitwillige
Aufuahme in eine bewiihrte Buchreihe.
Miinchen / Friedberg, im November 1997 Henning Mitte1bach
Inhalts'Verzeiehnis
Einleitung 7
Quell-und Objektcode; Hohere Programmiersprachen; etwas Historie; Rechner
und Zahlensysteme; die Rolle von C++
2 Die IDE von Borland 21
Zum ersten Umgang mit der Arbeitsumgebung von C++; die wichtigsten
Optionen der IDE: Editor, Compiler, Hilfestellungen
3 Erste Programme in C++ 27
Struktur eines C-Programms; Schliisselworter, Bezeichner, einfache Daten
typen; DOS-Programme; arithmetische u.a. Operationen; Standardfunktionen
4 Kontrollstrukturen 45
Verzweigungen; Schleifen; Darstellung durch Struktogramme; drei nicht
triviale A1gorithmen: quadratische Gleichung, Primzahlen, Iteration
5 Weitere Datentypen 64
Aufziihlungstypen, Arrays, Verbund; einige Listings mit entsprechenden
Anwendungen: u.a. Matrizenmultiplikation; Simulationen per Zufall
6 Exteme Dateien 75
Datenstrome; Formatierungen; Ausgaben am Drucker: zunachst unter DOS;
Abspeichern auf der Peripherie: Daten-und Textfiles; Strings
7 Funktionen 87
Der Funktionsbegriffin C++, Ausgestaltung der Schnittstelle (Call by Value);
Rekursive Aufrufe; die Sonderrolle von main ( ); Kommandozeiienparameter
8 Zeiger und Adressen 103
Einfiihrung des Begriffes Zeiger; Call by Reference; Weiterschalten am Heap;
Vorwiirtsverkettung bei einer kleinen Datei; Beispiel einer Ringiiste
9 Programmen~cklung 123
Eine kleine Adressenverwaltung aus Kap. 8; Binarsuche auf der Peripherie;
DatenverwaItung mit Indizes
6
10 Algorithmen 141
Ein Binarbaum; Quicksort und Sortieren nach Dijkstra; ein Hexdump-Programm;
Programme mit internen Kennungen; Kopierschutz von Exe-Files
11 Kryptologie 161
Asymmetrische Vetfahren wie RSA; ein symmetrisches Vetfahren mit Primzahlen;
Geheimnisse via Bildfile; Zeichenzahler und Wortlangen in Texten
Jetzt beginnt das Konzept von OOP :
12 Das Klassenkonzept 175
Das neue Paradigma: Klassen und Objekte; Attribute und Methoden statt Daten
und Funktionen; Konstruktoren; ein Spiel u.a. Beispiele; die Hintertiire friend
13 Die Klasse Mat 191
Am Beispiel einer Klasse Matrix wird mit Methoden von OOP eine Algebra
aufgebaut: Multiplizieren und Invertieren quadrati scher Matrizen
14 Objekte und Zeiger 203
Zeiger (Pointer) auf Objekte im Heap; Listings zum Umgang mit OOP-Objekten,
die peripher gespeichert werden sollen
15 Templates 217
Funktionsschablonen erleichtern das Programmieren: Beispiel Sortieren;
Klassentemplates: Beispiel Automat; Heap und virtueller Stack
16 Hierarchien 229
Das Prinzip der Vererbung von Attributen und Methoden; Uberschreiben von
Methoden; Polymorphismus, fruhes und spates Binden; Destruktoren
17 Ein Projekt in OOP 245
Entstehung des OOP-Programms Binarbaum; Drucken unter Windows
18 Klassische Aufgaben 263
Ubungsaufgaben mit ersten Losungsvorschlagen, Hinweise zur Grafik in C++
19 Aufgaben mit OOP-Ansatz 283
Eirtige Aufgaben mit objektorientierten Losungsansatzen
20 Glossar 299
Kleines Worterbuch zu Begriffen aus dem Umfeld des Buchs
21 Literatur 313
Biicherliste mit ,,Kurzrezensionen"
22 Stichwortverzeichnis, die Disk zum Buch 316
EinJeitung
In dies em Kapitel fmdet der Anfiinger allgemeine Hintergrundinformationen
zom Umfeld von Rechnern und zu Programmiersprachen, insb. C++ •
Die Steuerung von Cotnputem erfolgt tells iiber Kommandos direkt von der
Betriebssystemebene aus, tells iiber sog. Programme: Das sind letztlich Folgen von
Bitmustem, die von der CPU (Central Processor Unit) des Rechners direkt verstanden
und nacheinander (sequentiell) abgearbeitet werden. Solche prozessorabhiingigen
Maschinenprogramme (object code) konnen zwar auch seIber entwickelt werden,
doch ist das relativ schwierig und damit recht fehlertrachtig.
Heutzutage bedient man sich hauptsachlich sog. hOherer Programmiersprachen, die auf
ganz verschiedenen Rechnem einsetzbar, kompatibel sind. Die weit verbreiteten PCs
gehOren meistens zur Familie der DOS-Rechner mit Prozessoren der Baureihen 80486
bis zum Pentium Vorlaufer 1 dieser Prozessoren wie der 8086, 80286 und 80386 sind
inzwischen total veraltet, nur noch Auslaufinodelle
00.
Die im Laufe dieses Kurses vorkommenden Programme, die wir in der sog. C++
Sprachumgebung von Borland entwickeln werden, laufen auf diesen PCs unter DOS
wie Windows 2 ohne Probleme, auch auf Workstations unter dem Betriebssystem Unix
u. dgl. Absolute Neulinge im Umgang mit PCs seien auf ein Kapitel in [MI]
hingewiesen, das den ersten Umgang mit dieser Rechnerfamilie erleichtert und jene
Begriffe (z.B. Betriebssystem DOS) erklart, die wir hie und da verwenden werden.
1 AT steht bei mM fUr Advanced Technology bis etwa 1990, XT fUr Small
Technology der noch alteren PCs bis zum 8086, der schon Mitte der Achtziger auslief;
die Prozessoren der Baureihe 8086 ff stammen von INTEL, CYRIX, AMD u.a.
00'
Zur Installation von Borland C++ muB aber eine Festplatte vorhanden sein!
2
H. Mittelbach, Programmieren in C++ Borland-Versionen
© B. G. Teubner Stuttgart 1998
8 Einleitung
Eine hohere Programmiersprache wie BASIC, Pascal oder C++ ist eine ganz
speziell entwickelte Kunstsprache, eine sog. formale Sprache, nach W ortwahl und
Anzahl der Worter ein sehr kleiner Ausschnitt aus einer lebenden Sprache (meist
Englisch), und zwar mit priiziser Eingrenzung der Semantik (etwa: Bedeutungs
inhalt), und im Blick aufmaschine11e Bearbeitung sehr strenger Syntax (Grammatik).
Die Worter werden mit dem anglo-amerikanischen Alphabet (also ohne Umlaute etc.)
gebildet; hinzu kommen die Zift'em zum Aufbau der Zahlen, femer noch a11erhand
Sonderzeichen, mit denen z.B. Steuersequenzen gesendet werden konnen. Die lauf
fahigen Bausteine solcher Sprachen heillen Anweisungen (statements); jede zuliissige
Anweisung bewirkt eine genau definierte Reaktionsfolge des Computers. ,,zuliissig" ist
eine Anweisung dann, wenn sie aus den vorab definierten Elementen der Sprache
syntaktisch regelgerecht aufgebaut ist. Man muB also sowohl diese Syntax lemen als
auch die Bedeutung der Sprachelemente kennen, um die gewiinschte Wirkung sicher
zu erzielen.
Wissenschaftstheoretisch: Eine Programmiersprache ist ein abgeschlossenes System
mnemotechnisch (zum Erinnem) gUnstig formulierter Anweisungen zur Steuerung
eines Automaten. - ,,Abgeschlossen" bedeutet, daB jede sinnvo11e Verknupfung von
Anweisungen nach den geltenden Regeln zu neuen Anweisungen und damit wiederum
zu einer spezifischen Aktion des Automaten fiihrt. Eine endliche (!) Menge zuliissiger
Anweisungen zu einem bestimmten Zweck heillt Programm, ist Abbild eines
Algorithmus zur Losung irgendeines Problems. Programmieren in diesem a11-
gemeinen Sinn ist eine weitgefacherte Tiitigkeit: Man mul3 das Problem analysieren,
sich einen Losungsweg ausdenken und sachgerecht formulieren sowie zuletzt den
Algorithmus in einer passenden Sprache codieren, ehe man einen Rechner hinzuzieht.
Kein Wunder also, daB die mittlerweile ausgefeilte Rechnertechnik und die Vielfalt
differenzierter Probleme, die mit Rechnem untersucht werden konnen, viele dieser
Einzelschritte Spezialisten zuweisen. ,,Programmieren" steht daher in engerem
Wortsinn nur noch fUr einen einzigen der Arbeitsschritte, niimlich das Codieren des
Algorithmus zum Que11programm.
Diese Arbeit unterstUtzt ein bei Bedarf verfiigbares Programm des jeweiligen Sprach
systems, das zusiitzlich zum Betriebssystem des Rechners geladen werden mul3. 1m
Falle Borland C++ handelt es sich urn die o.g. sehr aufWendige Sprachumgebung IDE,
ein Werkzeug, das neben diesem Obersetzer eine ganze Reihe weiterer Komponenten
aufWeist, vor a11em einen Editor zum Erste11en und Bearbeiten der Quelltexte in C++,
femer einen Debugger zur Fehlersuche in bereits lauffahigen Programmen und noch
andere praktische Features.
Damit der Rechner das in einer Hochsprache geschriebene QueUprogramm (source
code) abarbeiten kann, muB es erst in ein Bitmuster "ubersetzt", in ein maschinen
orientiertes Objektprogramm verwandelt werden.
Einleitung 9
Zwei grundsiitzlich verschiedene Typen solcher Ubersetzer existieren: Wird das Quell
programm unter Laufzeit (Runtime) Zeile fUr Zeile iibersetzt und sogleich zeilen
weise abgearbeitet, so spricht man von einem Interpreter. Charakteristisch ist fUr
diesen Fall, daB ein Programm auch mit fehlerhaften Anweisungen gestartet werden
kann, weil solche erst unter Laufzeit erkannt werden. Interpretierte Programme sind
relativ langsam, da beijeder AusfUhrung neuerlich iibersetzt werden muB.
Ein Compiler hingegen generiert vorab den vollstiindigen Maschinencode und
speichert ihn auf Wunsch auch dauerhaft ab; nur bei erfolgreicher Ubersetzung steht
(auch ohne Quelle) ein syntaktisch fehlerfreier Objektcode zur Verfiigung, der dann
wiederholt sehr schnell abgearbeitet werden kann. DaB jenes Programm dann ')iiuft",
spricht noch lange nicht fUr seine ,,Richtigkeit", denn semantische oder logische Fehler,
letztlich Fehler im Algorithmus, werden auch von Compilem nicht oder nur selten
erkannt. Kann z.B. bei einem Quotienten der Nenner Null werden, so muB dies der
Programmierer durch eine Abfi-age im Programm vorab berucksichtigen ...
Hohere Programmiersprachen waren - zumindest anfangs - fast immer problem
orientiert, d.h. fUr einen ganz gewissen Zweck konzipiert. Das zeigt oft schon der
Name:
ALGOL: ALGOrithmic Language,
BASIC: Beginners All purpose Symbolic Instruction Code,
COBOL: COmmon Business Oriented Language,
FORTRAN: FORmula TRANslator u.a.
ALGOL und FORTRAN sind mathematisch-naturwissenschaftlich, COBOL ist kauf
miinnisch ausgerichtet. Baustatiker haben ihre eigene(n) Programmiersprache(n) mit
sehr speziellem Anweisungsvorrat und einer passenden Sprachstruktur. BASIC ist
meist in ein interpretierendes Sprachsystem eingebunden (es gibt aber auch BASIC
Compiler), die anderen genannten Sprachen werden stets compiliert. Das gilt auch fUr
C++. Allen gerade aufgefiihrten Sprachen ist gemeinsam, daB das zu losende Problem
algorithmisiert werden moB, der Losungsweg also sehr detailliert prozedural zu
beschreiben ist. Man nennt sie daher zusammenfassend prozedurale Sprachen. Auch
Pascal und C++ gehOren zu dieser Gruppe.
Hingegen ist z.B. PROLOG (PROgramming in LOGics) eine sog. deklarative
Sprache (der fiinften Generation): Ein Programm beschreibt die Aufgabe (z.B. das
bekannte Problem des Handelsreisenden) sinnflillig; der Rechner sucht dann eine
Losungsstrategie. PROLOG gehOrt zur groBen Grnppe der symboliscben Sprachen,
in der es neben den deklarativen auch noch applikative und logische gibt. Die
Programmiertechnik ist hier gegeniiber Pascal oder C++ meist deutlich anders. Immer
mehr an Bedeutung gewinnen sog. objektorientierte Sprachen; C++ als Erweiterung
der Sprache C gehOrt zu dieser Grnppe.
10 Einleitung
Die Sprache C++ ist eine Weiterentwicklung von C und enthalt jene Sprache als
Untermenge. Sie entstand ab etwa 1980, als Bjame Stroustrup das Klassenkonzept in
C verwirklichte: daher C++ als Inkrement von C: "C with classes". Die Entwicklung
von C wiederum hiingt eng mit dem Betriebssystem Unix zusammen, das schon vorher
fur Gr06rechner konzipiert worden war und die Sprache BCPL (Basic Combined
Programming Language) zur Grundlage hatte. C ist als Weiterentwicklung von B zu
verstehen, einem Derivat von BCPL. Hintergrund der damaligen Uberlegungen war es,
eine gut portable Sprache zu entwickeln, deren Konstrukte nicht zu hardwarenah
ausgelegt sein durften.
Als Bibel der C-Programmierer galt und gilt ein Buch von Brian Kemingham und
Dennis Ritchie, The C Programming Language, vergleichbar mit einem Manual von
Wirth zur Sprache Pascal. Man spricht daher geme vom K&R-Standard. Der
derzeitige Standard von C++ ist seit 1995 in einem Dokument der Amerikanischen
Normungskommission ANSI festgelegt, siehe z.B. [E].
C und bald auch C++ kann als derzeitige Programmiersprache Nummer eins ange
sehen werden; an ihr kommt kein professioneller Programmierer vorbei. Allerdings ist
C++ schwerer erlembar als z.B. Pascal oder gar BASIC; das vorliegende Buch ist in
erster Linie fur Umsteiger aus einer anderen, gut strukturierenden Sprache wie Pascal
gedacht, kann aber auch von echten Anfangem benutzt werden. Eine Standort
bestimmung findet sich im Vorwort.
Sehen Sie sich zunachst die dargestellten Listings (Quellprogramme) zu ein und
derselben Aufgabenstellung in C++ und dann in weiteren Sprachen auf der Seite
gegeniiber an:
In allen Fallen handelt es sich urn dieselbe Aufgabe: Es sind sechs ganze Zahlen von
der Tastatur einzulesen, deren Summe gebildet und dann ausgegeben wird. In C++
sieht das etwa so aus:
# include <iostream.h> C++
main ()
=
{ int summe 0 ;
=
for ( int k 0 ; k < 6 ; k++ )
{ int a ; cin » a ; summe = summe + a ; }
cout « "Summe ... : " « summe ;
return (0) ;
}
Die restlichen Listings leisten in etwa dasselbe, lassen das aber im FaIle ALGOL,
Version 1960 (eine deutsche Entwicklung) bzw. FORTRAN IV (zeitlich friiher, ab
1954 von ffiM) keineswegs so einfach erkennen, auch wenn z.B. die sog. FOR
Schleife in drei der Listings in vergleichbarer Weise auftritt.