Springer-Lehrbuch - Antonio Ceballos Fotografía

Werbung
Springer-Lehrbuch
Martin Schader
Stefan Kuhlins
Programmieren in C++
Einfiihrung in den
Sprachstandard C++ Version 3.0
Mit 25 Abbildungen
Springer-Verlag
Berlin Heidelberg New York
London Paris Tokyo
Hong Kong Barcelona
Budapest
Professor Dr. Martin Schader
Dipl.-Wirtsch.-Inf. Stefan KuWins
Universität Mannheim
Lehrstuhl für Wirtschaftsinformatik m
Schloß
D-6800 Mannheim 1
ISBN-13: 978-3-540-56524-6
DOI: 10.1007/978-3-642-97490-8
e-ISBN-13: 978-3-642-97490-8
Dieses Werk ist urheberrechtlich geschützt. Die dadurch begründeten Rechte, insbesondere die der Übersetzung, des Nachdruckes, des Vortrags, der Entnahme von Abbildungen
und Tabellen, der Funksendungen, der Mikroverfilmung oder der Vervielfältigung aufanderen Wegen und der Speicherung in Datenverarbeitungsanlagen, bleiben, auch bei nur
auszugsweiser Verwertung, vorbehalten. Eine Vervielfältigung dieses Werkes oder von
Teilen dieses Werkes ist auch im Einzelfall nur in den Grenzen der gesetzlichen Bestimmungen des Urheberrechtsgesetzes der Bundesrepublik Deutschland vom 9. September
1965 in der Fassung vom 24. Juni 1985 zulässig. Sie ist grundsätzlich vergütungspflichtig.
Zuwiderhandlungen unterliegen den Strafbestimmungen des Urheberrechtsgesetzes.
© Springer-Verlag Heidelberg 1993
Die Wiedergabe von Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw. in
diesem Werk berechtigt auch ohne besondere Kennzeichnung nicht zu der Annahme, daß
solche Namen im Sinne der Warenzeichen- und Markenschutz-Gesetzgebung als frei zu
betrachten wären und daher von jedermann benutzt werden dürften.
4217130-543210 - Gedruckt auf säurefreiem Papier
Vorwort
Der Einsatz objektorientierter Techniken in allen Phasen der Softwareentwicklung
- in der Analyse- und Designphase und bei der Implementierung - hat das Interesse an der Programmiersprache C++ in den letzten Jahren ständig größer werden
lassen. Entsprechend hat sich auch das Angebot verfügbarer C++-Compiler auf
unterschiedlichsten Hardware-Plattformen und Betriebssystemen stetig vergrößert.
Bei der Erstellung dieses Lehrbuchs haben wir Borland C++ 3.1 unter MS-DOS
Version 5.0 und AT&T cfront 3.0.1 unter Sun-OS 4.1.3 benutzt, da es sich dabei
unserer Ansicht nach um die derzeit am weitesten verbreiteten Compiler für MSDOS- bzw. UNIX-Systeme handelt. Alle in den nachfolgenden Kapiteln vorgestellten
Beispielprogramme können unverändert mit beiden Compilern übersetzt werden.
Auf Unterschiede oder Einschränkungen bei den Kurzbeispielen weisen wir jeweils
im entsprechenden Zusammenhang hin.
Die Sprache C++ befindet sich derzeit noch im Stadium der endgültigen Normierung. Es gibt jedoch ein C++-Komitee (Technical Committee X3J16 Programming
Language) des ANSI (American National Standards Institute), das 1990 seine Arbeit
aufgenommen hat. Dieses Komitee hat die Publikation M.A. Ellis, B. Stroustrup,
The Annotated C++ Reference Manual, Addison-Wesley, Reading, 1990 als Grundlage (base document) für die formale St~ndardisierung gewählt. Die Verabschiedung
des Standards wird nicht vor 1995 erwartet. Die vom Komitee jeweils diskutierten
Unterlagen kann man als Working Paper for Draft Proposed American National
Standard for Information Systems - Programming Langua,ge C++ vom X3 Secretariat, CBEMA, 1250 Eye Street, NW Suite 200, Washington DC 20005-3922, USA
anfordern.
Der im vorliegenden Buch beschriebene Sprachumfang ist der in Ellis, Stroustrup
(1990) beschriebene - aktualisiert durch das neueste AT&T C++ Reference Manual (derzeitiger Stand: Mai 1991). Die jeweils aktuellste Version dieses Manuals
kann direkt über das AT&T Customer Information Center, 2855 N. Franklin Road,
Indianapolis, IN 46219-1385, USA bezogen werden.
Unser Buch beinhaltet keine Darstellung des gesamten (noch nicht vollständig normierten) Inhalts der C++-Standardbibliothek; nur die benutzten Funktionen werden kurz erläutert. Das Buch ist aus einem Vorlesungszyklus über objektorientierte
Methoden, der an der Universität Mannheim gehalten wird, entstanden. Es wendet
sich an Leser, die über Grundkenntnisse von Rechnern und ihrer Programmierung
verfügen und mit den Begriffen Compiler, Linker, ... und ihrer Umgebung vertraut
sind.
Die einzelnen Sprachkonstrukte werden anhand vieler Programmfragmente und kleiner Beispielprogramme erklärt. Diese Beispiele sind in keiner Weise als vollständig
sondern lediglich als illustrativ für den jeweils diskutierten Gegenstand anzusehen;
sie sind in der Regel sehr kurz gehalten und es wurde wenig Wert auf Algorithmik
oder möglichen Effizienzgewinn durch Schreiben von "C++-Puzzles" gelegt. Fast
immer wurde auf Fehlerbehandlung und Kommentare verzichtet, die beide bei für
vi
den praktischen Einsatz vorgesehenen Programmen unerläßlich sind. Eine komplette
Fehlerbehandlung und Kommentierung würde den Umfang der Programme mindestens verdoppeln oder verdreifachen. Die Leser müssen sich darüber im klaren sein,
daß hier noch eigenständig weiterentwickelt werden muß.
Wir empfehlen, die Programmbeispiele parallel zum Lesen sukzessiv fortzuschreiben.
Wenn im Text auf eine Klasse verwiesen wird, ist immer die bis dahin implementierte
Version gemeint.
Am Ende der meisten Kapitel ist eine Reihe von Übungsaufgaben zusammengestellt, mit denen der behandelte Stoff vertieft werden kann. Gegen Einsendung
einer MS-DOS-formatierten 3t"-Diskette mit frankiertem Rückumschlag an die auf
den Umschlagseiten angegebene Anschrift sind unsere Lösungsvorschläge erhältlich.
Über Mitteilungen und Anregungen der Leserinnen und Leser würden wir uns freuen.
Wer uns einen Fehler (gleichgültig welcher Art) zuerst mitteilt, wird ggf. im Vorwort
der nächsten Auflage namentlich erwähnt.
Dr. Werner A. Müller und seinen Mitarbeitern beim Springer-Verlag, Heidelberg,
gilt unser Dank für die - wie immer - ausgezeichnete Zusammenarbeit.
Mannheim, Januar 1993
Martin Schader, Stefan K uhlins
Inhalt
1 Einleitung
1.1 Grundbegriffe
1.2 Syntaxnotation
1
1
2
2 Lexikalische Konventionen
2.1 Ein erstes Beispiel . . .
2.2 Lexikalische Elemente.
2.3 Kommentare..
2.4 Bezeichner . . .
2.5 Schlüsselwörter
2.6 Operatoren ..
2.7 Header-Dateien
3
3
3 Vordefinierte Datentypen
9
4 Literalkonstanten
4.1 Ganzzahlige Konstanten
4.2 Zeichenkonstanten ..
4.3 Gleitpunktkonstanten .
4.4 Zeichenketten
4.5 Beispiele........
13
5 Variablen und Konstanten
5.1 Einleitung . . . . . . . . . . . . . . . . . .
5.2 Deklaration und Definition von Variablen.
5.3 Symbolische Konstanten
5.4 L-Werte
5.5 Beispiel . . . . . . . . .
19
6 Typumwandlungen und Ausdrücke
6.1 Standardkonversionen .
6.2 Ausdrücke....
6.3 Übungsaufgaben
27
7 Anweisungen
7.1 Einleitung . . . . . . .
7.2 Ausdrucksanweisungen
7.3 Auswahlanweisungen
7.4 Wiederholungsanweisungen .
7.5 Sprunganweisungen
7.6 Beispiel . . . . . . . . . . .
45
45
4
4
4
5
5
6
13
14
15
16
17
19
21
23
24
24
27
30
42
46
47
50
53
54
viii
7.7 Übungsaufgaben
. . . . . . . . . . . . . . . . . . . . . . . . . . 55
8 Abgeleitete Datentypen
8.1 Felder . . . .
8.2 Zeichenfelder ..
8.3 Zeiger . . . . . .
8.4 Zeigerarithmetik
8.5 Zeiger und Felder
8.6 Die Operatoren new und delete .
8.7 Referenzen . . . . . . . .
8.8 Aufzählungstypen . . . . .
8.9 Typnamen und typedef .
8.10 Der abgeleitete Typ void*
8.11 Übungsaufgaben . . . . .
57
57
61
62
66
68
9 Typumwandlungen
9.1 Standardkonversionen .
9.2 Explizite Typumwandlungen
9.3 Übungsaufgaben . . . . . .
87
87
87
90
10 Geltungsbereiche und Lebensdauer
10.1 Geltungsbereiche . . . . . . . .
10.2 Die Lebensdauer von Objekten
10.3 Übungsaufgaben . . . . . . . .
91
91
95
98
11 Funktionen
11.1 Deklaration und Definition von Funktionen.
11.2 Funktionsaufruf und Argumentübergabe
11.3 Die Rückgabe von Funktionswerten
11.4 Referenzargumente ..
11.5 Felder als Argumente . . . . .
11.6 Zeiger auf Funktionen . . . .
11.7 Der Geltungsbereich Funktion
11.8 Standardargumente . . . . . .
11.9 Unspezifizierte Argumente ..
11.10 Die Funktionen mainO und exitO
11.11 inline-Funktionen .
11.12 Übungsaufgaben . . . . . . .
72
77
80
81
83
85
101
· 101
· 104
.106
· 107
· 109
· 111
.114
· 115
.116
· 119
.119
· 121
125
12 Externe und interne Bindung
13 Überladene Funktionsnamen
13.1 Einleitung . . . . . . . . . . . . . . . .
13.2 Funktionen mit einem Argument .. .
13.3 Funktionen mit mehreren Argumenten
13.4 Zeiger auf überladene Funktionen . . .
·
·
·
·
133
133
136
140
142
ix
13.5 Übungsaufgaben
· 143
14 Klassen
14.1 Deklaration und Definition von Klassen.
14.2 Klassenobjekte . . . . . . . . . . . . .
14.3 Der Geltungsbereich Klasse . . . . . .
14.4 Die Spezifizierung von Zugriffsrechten .
14.5 Der Zeiger this . . . . . . . . . . . . .
14.6 Namensdeklarationen . . . . . . . . . .
14.7 Die Konstruktion von Klassenobjekten
14.8 Destruktoren . . . . . . . . . . . . . .
14.9 Als eonst deklarierte Elementfunktionen
14.10 friend-Funktionen . . . . .
14.11 statie Klassenelemente ..
14.12 inline-Elementfunktionen
14.13 Zeiger auf Klassenelemente
14.14 Klassenobjekte als Klassenelemente .
14.15 Lokale Typnamen . . . . . . . .
14.16 Bitfelder . . . . . . . . . . . . .
14.17 Die Bindung von Klassennamen .
14.18 Reader-Dateien.
14.19 Übungsaufgaben . . . . . . . . .
145
· 145
.147
· 148
· 152
· 155
· 156
· 160
· 167
· 169
.172
· 175
.179
· 181
· 185
· 188
· 189
· 191
· 194
· 197
15 Spezielle Konstruktoren
15.1 Der Copy-Konstruktor . . . . . . . . . .
15.2 Typumwandlungen mittels Konstruktor .
15.3 Übungsaufgaben . . . . . . . . . . . . .
.201
· 205
.207
16 Überladene Operatoren
16.1 Einleitung . . . . . . .
16.2 Der Zuweisungsoperator =
16.3 Einstellige Operatoren ..
16.4 Zweistellige Operatoren ..
16.5 Typumwandlungen mittels Konversionsfunktion
16.6 Übungsaufgaben . . . . . . . . . . . . . . . . .
.209
.210
· 212
· 215
· 219
· 221
17 Abgeleitete Klassen
17.1 Einfache Vererbung . . . . . . . . . . . . . . . . . .
17.2 Der Zugriff auf Klassenelemente . . . . . . . . . . .
17.3 Standardkonversionen von Zeigern und Referenzen.
17.4 Virtuelle Funktionen
17.5 Abstrakte Klassen. . .
17.6 Mehrfachvererbung . .
17.7 Virtuelle Basisklassen .
17.8 Spezielle Zugriffsrechte
.225
.229
.233
.239
.245
.248
· 252
.256
201
209
225
x
17.9 Übungsaufgaben
.260
18 Parametrisierte Funktionen und Klassen
18.1 Einleitung . . . . . . . . . .
18.2 Parametrisierte Funktionen
18.3 Parametrisierte Klassen.
18.4 Übungsaufgaben . . . . . .
265
· 265
· 266
.273
.284
19 Streams
19.1 Einleitung . . . . . . . . . . . . . . . . . . . . . . .
19.2 Formatierung . . . . . . . . . . . . . . . . . . . . .
19.3 Ein- und Ausgabe benutzerdefinierter Datenobjekte
19.4 Ein- und Ausgabe mit Dateien.
19.5 Übungsaufgaben . . . . . . . . . . . . . . . . . . .
287
.287
.287
.288
· 290
.292
Anhang
A
ASCII-Tabelle.
B
Arithmetische Standardkonversionen
C
Operatorprioritäten .
D
Syntaxregeln . . .
E
Die Klasse Liste
.293
.294
.295
.296
· 298
Literaturverzeichnis
Index
293
302
303
1
Einleitung
In diesem Kapitel erläutern wir die drei für die Beschreibung jeder modernen Programmiersprache wichtigen Komponenten Symbolvorrat, Syntax
und Semantik. Anschließend wird die im weiteren verwendete Notation
der Syntaxregeln eingeführt.
1.1
Grundbegriffe
Bei der Beschreibung einer Programmiersprache sind die folgenden drei Aspekte zu
betrachten:
- Die lexikalischen Elemente der Sprache.
Die Menge der lexikalischen Elemente ist der sog. Symbolvorrat der Sprache.
Hierin sind die Wörter und Interpunktionszeichen enthalten, aus denen sich
korrekt gebildete Programme (das sind die Sätze der Sprache) zusammensetzen. Die lexikalischen Elemente von C++ werden in Kapitel 2 und Kapitel 4
diskutiert. Dort wird beschrieben, welche Form die Namen der in einem Programm auftretenden Variablen, Typen, Funktionen, etc. haben müssen, welche
Namen für den Compiler eine feste Bedeutung haben, so daß sie vom Programmierer nicht mehr für eigene Zwecke verfügbar sind und wie Zahlen und andere
Konstanten dargestellt werden.
- Die Syntax der Sprache.
Nicht jede Folge von lexikalischen Elementen ist bereits ein korrekt gebildetes
Programm. Welche Symbolfolgen zulässige Sätze der Sprache (das sind Programme, die der Compiler versteht und übersetzen kann) bilden, wird durch
die Syntax oder Grammatik der Sprache geregelt. Für die Beschreibung der
Syntax von C++ verwenden wir Syntaxregeln, deren Format im nächsten Abschnitt beschrieben ist.
- Die Semantik von Programmen.
Die Semantik gibt zu jedem Programm die zugehörige Bedeutung an, beschreibt also, welche Aktionen das Programm ausführt, wie eingegebene Daten verarbeitet werden bzw. mit welchen Berechnungen Ausgaben vorbereitet
1. Einleitung
2
werden. Wir werden die Semantik von C++-Programmen umgangssprachlich,
anhand vieler Beispiele, jeweils im Zusammenhang mit der Erläuterung neuer
Syntaxregeln erklären.
1.2
Syntaxnotation
Die Syntax einer Programmiersprache wird durch eine Zusammenstellung von Regeln (sog. Produktionsregeln) spezifiziert, die die korrekte Bildung von Programmen
beschreiben. Zur Darstellung der Regeln benutzen wir die in B. W. Kernighan, D.M.
Ritchie, The C Programming Language, Prentice Hall, 1978 eingeführte Notation.
Jede Regel beginnt mit einem nichtterminalen Symbol, auf das ein Doppelpunkt
und die Definition des Symbols folgen.
Terminale Symbole sind in Schreibmaschinenschrift gesetzt - sie werden unverändert in den Programmtext übernommen. In der Definition auftretende nichtterminale Symbole sind in anderen Regeln definiert. Alternativen stehen in verschiedenen Zeilen. In wenigen Ausnahmen wird eine lange Liste von Alternativen
auf einer Zeile angegeben; dies wird durch den Ausdruck "eins von" angezeigt. Ein
optionales terminales oder nichtterminales Symbol erhält den Index opt.
Beispielsweise beschreiben die beiden folgenden Regeln
C+ +-Programm:
Programm datei
C++-Programm Programmdatei
Programmdatei:
Deklaration
Programmdatei Deklaration
daß ein C++-Programm aus einer oder mehreren Programmdateien besteht, die
jeweils eine oder mehrere Deklarationen enthalten, und der Regel
Deklaration:
Dekl-Spezijiziererlisteopt Deklaratorlisteopt ;
Asm-Deklaration
Funktionsdejinition
Template- Deklaration
Bindungsspezijikation
kann man entnehmen, daß eine Funktionsdefinition eine Deklaration ist.
Die in diesem Lehrbuch zusammengestellten Syntaxregeln definieren die Sprache
C++ nicht vollständig. Gelegentlich werden sie durch eine weniger formale, verbale
Erläuterung ergänzt. Die obige erste Regel ist beispielsweise durch den Zusatz zu
vervollständigen, daß jedes C++-Programm eine Funktionsdefinition enthalten muß,
in der eine Funktion mit dem Namen main definiert wird. Somit ist ein einzelnes;
kein C++-Programm.
2
Lexikalische Konventionen
Anhand eines ersten Beispielprogramms werden wir in diesem Kapitel
in die Grundlagen von C++ einführen. Dazu stellen wir die lexikalischen Elemente: Kommentare, Bezeichner, Schlüsselwörter und Operatoren vor. Außerdem wird das Übersetzen und Ausführen eines ersten
C++-Programms besprochen.
2.1
Ein erstes Beispiel
Wir beginnen dieses Kapitel mit einem einfachen Programm, das die Fläche eines
Dreiecks bei gegebener Höhe und Grundseite berechnet:
1* prog-i
*
* Programm zur Berechnung der Flaeche eines Dreiecks
* mit vorgegebener Hoehe und Grundseite.
*1
#include <iostream.h>
II vgl. Abschnitt Header-Dateien
int mainO
{
int hoehe = 3;
int grundseite
5;
double flaeche
hoehe*grundseite*0.5;
cout « "Flaeche des Dreiecks: " « flaeche «
return 0;
'\n';
}
Bei Benutzung von Borland C++ speichert man dieses Programm am besten unter
dem Dateinamen prog-i. cpp ab und gibt, um es zu übersetzen, den Befehl bcc
prog-i ein. Man erhält dann als Ergebnis das lauffähige Programm prog-i. exe,
das mit der Eingabe prog-i gestartet werden kann. Für AT&T's cfront ist das zu
4
2.
Lexikalische Konventionen
übersetzende Programm mit dem Namen prog-l. C anzulegen. Der entsprechende Compiler-Aufruf lautet CC prog-1.C -0 prog-1. Als Resultat erhält man das
ausführbare Programm prog-l, das wieder mit prog-l gestartet wird.
Dieses Beispielprogramm wird in den folgenden Abschnitten dazu verwendet, die
elementaren Sprachelemente näher zu erläutern.
2.2
Lexikalische Elemente
Die kleinsten Einheiten, aus denen sich ein C++-Programm zusammensetzt, nennt
man lexikalische Elemente. Sie werden in fünf Klassen eingeteilt: Bezeichner, Schlüsselwörter und Interpunktionszeichen, Literalkonstanten, Operatoren und Trenner.
Zu den Trennern gehören Leerzeichen, Tabulatoren, Zeilenendezeichen, Seitenvorschübe und Kommentare. Sie werden dazu verwendet, die übrigen lexikalischen Elemente voneinander zu trennen. Zwischen aufeinanderfolgenden Bezeichnern, Schlüsselwörtern oder Literalkonstanten muß mindestens ein Trenner stehen - ansonsten
werden Trenner vom Compiler ignoriert. Trenner, die nicht Kommentare sind, werden auch als" white space" bezeichnet, da die entsprechenden Zeichen bei der Ausgabe des Programms auf Drucker oder Monitor nicht sichtbar sind.
Bei der Analyse eines Programmtextes werden vom Compiler immer die größtmöglichen lexikalischen Elemente gebildet, d.h. wenn ein kurzes in einem längeren Element
enthalten ist, wird das längere ausgewertet.
2.3
Kommentare
Es gibt zwei Arten von Kommentaren: Zeilenkommentare beginnen mit / / und
erstrecken sich bis zum Ende der Zeile, in der sie stehen. Kommentarblöcke werden
mit den beiden Zeichen /* eingeleitet und enden mit */. Sie können sich über
mehrere Programmzeilen erstrecken. Kommentarblöcke können nicht geschachtelt
werden. Allerdings haben innerhalb von Kommentarblöcken die Zeichen / / genauso
wenig eine spezielle Bedeutung, wie umgekehrt die Zeichen /* und */ innerhalb von
Zeilenkommentaren.
In unserem Beispielprogramm sind je ein Zeilenkommentar und ein Kommentarblock
enthalten.
2.4
Bezeichner
Bezeichner sind Namen, die der Programmierer für die von ihm definierten Variablen, Konstanten, Typen, Klassen oder Funktionen wählt. In C++ können Bezeichner beliebig lang sein, d.h. alle Zeichen sind signifikant. Sie müssen mit einem
Buchstaben oder dem Unterstrich _ beginnen. Daran anschließend sind kleine und
große Buchstaben von abis z bzw. Abis Z, Ziffern von 0 bis 9 und Unterstriche
erlaubt. Zwischen Groß- und Kleinschreibung wird unterschieden.
prog-l enthält die Bezeichner main, hoehe, grundseite, flaeche und cout.
2.5
Schlüsselwörter
5
Bezeichner, die mit einem oder mehreren Unterstrichen beginnen, sollte man vermeiden, da sie typischerweise in C++-Bibliotheken verwendet werden.
2.5
Schlüsselwörter
Die folgenden Schlüsselwörter sind in C++ reserviert und dürfen nicht anderweitig
(z.B. als Bezeichner) benutzt werden:
auto
const
else
goto
operator
short
template
unsigned
asm
class
double
friend
new
return
switch
union
break
continue
enum
case
default
extern
inline
protected
sizeof
throw
void
if
private
signed
this
virtual
catch
delete
float
int
public
static
try
volatile
char
do
for
long
register
struct
typedef
while
Die Schlüsselwörter catch, throw und try sind für die Ausnahmebehandlung (sog.
"exception handling") reserviert, auf die wir im folgenden nicht eingehen, weil sie
bei den von uns benutzten Compiler-Versionen noch nicht implementiert ist.
Eine Art abgekürzter Schlüsselwörter sind die Interpunktionszeichen von C++:
{
<
}
>
mit denen Anweisungen abgeschlossen oder in Blöcken zusammengefaßt werden,
Listenelemente voneinander getrennt werden, etc.
Das Beispielprogramm enthält die Schlüsselwörter int, double und return und die
Interpunktionszeichen C, ), {, } und ;. Wie in prog-l treten geschweifte, runde
oder spitze Klammern immer paarweise auf.
2.6
Operatoren
In C++ steht eine Vielzahl von Operatoren zur Verfügung - das sind Symbole, die
verschiedene Operationen auf ihren Argumenten, den sog. Operanden, ausführen:
[]
->*
%=
%
<
«
+=
>
»
&
?:
<=
«=
*
/
>=
»=
0
&=
!=
+
->
&&
1=
++
11
*=
.*
/=
In prog-l wird beispielsweise mit dem Multiplikationsoperator * das Produkt von
Höhe und Grundseite des Dreiecks berechnet und dieser Wert danach mit der Zahl
0.5 multipliziert. Mit dem Ausgabeoperator « werden dann der Text Flaeche
6
2. Lexikalische Konventionen
des Dreiecks:, die berechnete Dreiecksfiäche und ein Zeilenendezeichen ausgegeben.
Die Bedeutung der einzelnen Operatoren, ihre Wirkungsweise bei der Verarbeitung
der Werte ihrer Operanden und der Berechnung des Werts von Ausdrücken, die sich
aus Operatoren und Operanden zusammensetzen, werden in den folgenden Kapiteln,
insbesondere in Abschnitt 6.2 erklärt.
2.7
Header-Dateien
Die meisten in diesem Buch abgedruckten Beispielprogramme enthalten an ihrem
Anfang eine oder mehrere Zeilen der Art
#include <iostream.h>
Dies ist eine Anweisung an den Compiler, vor dem eigentlichen Übersetzungsvorgang
die entsprechende Zeile durch den gesamten Inhalt sog. Standard-Reader-Dateien,
hier iostream. h, zu ersetzen.
Standard-Reader-Dateien enthalten die Deklarationen von Funktionen, Typen, Klassen, usw., die strenggenommen nicht Bestandteil der Sprache C++ sind, aber bei
jeder C++-Implementierung in der Standard bibliothek zur Verfügung gestellt werden.
Um die Übersetzung von Programmen nicht grundlos aufwendig zu gestalten, wurden diese Deklarationen nach Funktionalität in verschiedene Reader-Dateien unterteilt. Z.B. befinden sich in iostream.h Deklarationen von Ein- und Ausgabefunktionen, in math. h Deklarationen von mathematischen Funktionen oder in time. h
Deklarationen von Funktionen zur Manipulation von Datum und Uhrzeit.
Standard-Reader stehen üblicherweise in einem Verzeichnis namens include oder
unterhalb davon (bei den von uns verwendeten Compilern in den Verzeichnissen
\borlandc\include bzw. /usr!include/CC). Wird der Name einer benötigten Reader-Datei wie oben - in < und> eingeschlossen - angegeben, so sucht der Compiler
die Datei in diesem speziellen include-Verzeichnis.
In den Abschnitten 14.17 und 14.18 werden wir zeigen, daß es bei der Programmierung von Klassen oft sinnvoll ist, die Spezifikation der Klasse (d.i. die Information,
die ein Programm benötigt, das die Klasse benutzt) und die eigentliche Implementation der Klasse voneinander zu trennen, und die Klassenspezifikation in einer
Reader-Datei abzulegen.
In diesem Fall gibt man den Namen der Reader-Datei im Anwendungsprogramm in
" und " eingeschlossen an, z.B.
#include "DoubMenge.h"
Der Compiler sucht die Datei dann zunächst im aktuellen Verzeichnis; falls er sie
dort nicht findet, verfährt er, als sei #include <DoubMenge. h> angegeben.
2.7
Header-Dateien
7
Bemerkung
Wie in Abschnitt 2.2 erwähnt, ist die Verwendung von Trennern bis auf die beschriebenen Ausnahmen option al. prog-l könnte man daher auch wie folgt eingeben:
#include<iostream.h>
int main(){int hoehe=3;int grundseite=5;double flaeche=hoehe*
grundseite*O.5;cout«"Flaeche des Dreiecks: "«flaeche«'\n';
return O;}
Es ist in das Ermessen des Programmierers gestellt, welche Form ihm geeignet und
verständlich erscheint. Wir haben uns im folgenden an der Notation orientiert, die
in Lippman (1991), Meyers (1992) oder Stroustrup (1991) benutzt wird.
3
Vordefinierte Datentypen
Wie in den meisten Programmiersprachen gibt es in C++ vordefinierte
- in die Sprache eingebaute - Datentypen und die entsprechenden Operatoren. Diese Typen, die die Grundlage aller vom Programmierer selbst
abgeleiteten Typen sind, werden im folgenden Kapitel eingeführt.
Die von einem Programm zu verarbeitenden Daten werden, wie auch der eigentliche
Programmcode, im Speicher des Rechners als Bitfolgen abgelegt.
Solche Speicherinhalte erhalten erst durch Angabe ihres Datentyps eine sinnvolle Interpretation. C++ stellt hierzu eine Reihe vordefinierter Datentypen zur Verfügung.
Aus den vordefinierten Typen werden alle anderen in einem Programm verwendeten
Datentypen abgeleitet. (Diese Typen werden in den Kapiteln 8, 11 und 14 besprochen.) Jedem Bezeichner muß genau ein Datentyp zugeordnet sein, der festlegt,
welche Operationen für den Bezeichner definiert sind, wieviel Speicherplatz reserviert wird und welche Werte dem jeweiligen Speicherinhalt entsprechen. Mit dem
Typ wird also auch ein Wertebereich, d.h. die Menge der Werte, die eine Variable,
Konstante, etc. annehmen kann, festgelegt.
Die vordefinierten Datentypen werden in arithmetische Typen und den Typ void
unterteilt; ein arithmetischer Typ ist entweder ein ganzzahliger Datentyp oder ein
Gleitpunkttyp.
Zu den ganzzahligen Typen gehören char, short int, int, long int und die in
Abschnitt 8.8 erläuterten Aufzählungstypen. Mit ihnen repräsentiert man ganze
Zahlen verschiedener Größe sowie einzelne Zeichen.
Der Datentyp char kann jedes Zeichen aus dem Zeichensatz der verwendeten C++Implementierung aufnehmen. Der in einem char gespeicherte Wert entspricht dabei
der Ordinalzahl des Zeichens im jeweiligen Zeichensatz. In der Regel belegt er ein
Byte.
Das Schlüsselwort sizeof kann als einstelliger Operator verwendet werden und gibt
dann die Größe eines Typs in Vielfachen des Typs char an. Per Definition ist daher
sizeof(char)
= 1.
10
3. Vordefinierte Datentypen
Im Reference Manual wird garantiert, daß die folgenden Beziehungen von jeder
Implementierung erfüllt werden:
1 = sizeof(char)
~
sizeof(short int)
~
sizeof(int)
~
sizeof(long int).
Welche Wertebereiche tatsächlich realisiert sind, ist dem Standard-Reader limits.h
zu entnehmen. Minimalanforderungen an einen C++-Compiler sind:
char
short int
int
long int
o
-32767
-32767
-2147483647
127
32767
32767
2147483647
Die beiden auf den Typnamen folgenden Zahlen geben hier jeweils die Unter- bzw.
Obergrenze des Wertebereichs an, der mindestens zur Verfügung gestellt werden
muß.
Alle ganzzahligen Typen können explizit als signed bzw. unsigned deklariert werden. Somit lassen sich acht Kombinationen bilden:
unsigned char
unsigned short int
unsigned int
unsigned long int
signed char
signed short int
signed int
signed long int
Wie die Namen bereits andeuten, steht unsigned für Typen ohne Vorzeichen, die
nur positive Werte annehmen können und signed für Typen mit Vorzeichen, deren
Werte auch negativ sein können. Wie das Vorzeichen behandelt wird, ist maschinenund implementationsabhängig - bei den beiden von uns verwendeten Compilern
ist dafür jeweils das höchstwertige Bit reserviert. Damit unterscheidet sich ein
unsigned Wertebereich von dem entsprechenden signed Wertebereich lediglich dadurch, daß er so verschoben wurde, daß er bei 0 beginnt und entsprechend größere
Zahlen enthält.
Bei jedem C++-Compiler ist
sizeof(T)
= sizeof(signed
T)
= sizeof(unsigned
T),
wobei Tfür char, short int, int oder long int steht. Wenn nichts angegeben ist,
wird standardmäßig signed angenommen, d.h. int und signed int haben denselben Effekt - der Typ char bildet allerdings eine Ausnahme: hier ist es der jeweiligen
Implementation überlassen, ob ein char als signed char oder unsigned char behandelt wird.
3.
Vordefinierte Datentypen
11
Die Gleitpunkttypen in C++ sind float, double und long double. Ihre Wertebereiche sind jeweils eine Teilmenge der rationalen Zahlen. Ähnlich wie bei den
ganzzahligen Typen ist garantiert, daß
sizeof(float) :::; sizeof(double) :::; sizeof(long double)
gilt. Details der verfügbaren Wertebereiche stehen in der Reader-Datei float. h.
Jeder C++-Compiler muß jedoch mit den drei Gleitpunkttypen mindestens die rationalen Zahlen, deren Betrag zwischen 10-37 und 1037 liegt, darstellen können.
Dabei müssen float- Werte mindestens 6, double- und long double-Werte mindestens 10 signifikante Dezimalziffern haben.
Stehen beispielsweise im Speicher ab einer bestimmten Adresse die folgenden Bits
01000001 01000010 01000011 01000100
-
aufsteigende Adressen
und werden diese Bits als float-Wert interpretiert, so ist das Ergebnis beim Borland- bzw. AT&T-Compiler die Zahl 781.035217 bzw. 12.141422. Ein long int
ergibt 1145258561 bzw. 1094861636, und bei Interpretation als vier chars erhält
man jeweils A, B, C und D. Man sieht, daß beide Compiler zur Darstellung von Zeichen
den ASCII-Code verwenden (American Standard Code for Information Interchange),
der in Anhang A abgedruckt ist. Wie oben bemerkt, wird in einem char jeweils die
Ordinalzahl des entsprechenden Zeichens gespeichert, im Beispiel also 65 für A, 66
für B, etc. Die unterschiedlichen Ergebnisse bei den arithmetischen Typen kommen
dadurch zustande, daß zusammengehörige Bytes von den verwendeten Prozessoren
in umgekehrter Reihenfolge aneinandergefügt werden.
Der vordefinierte Datentyp void bezeichnet eine leere Wertemenge. Wir werden
ihn im folgenden als Typ des Funktionswerts bei Funktionen verwenden, die keinen Wert zurückgeben. Variablen vom Typ void sind aus naheliegenden Gründen
nicht zulässig. void - und insbesondere der abgeleitete Typ Zeiger auf void wurde bei früheren Compiler-Versionen zur Definition von Funktionen mit variablen Argumenttypen oder Klassen mit variablen Elementtypen verwendet. Mit der
Verfügbarkeit sog. parametrisierter Funktionen und Klassen (vgl. Kapitel 18) sind
derartige Konstruktionen nicht mehr interessant.
Bemerkung
Der Vollständigkeit halber, und zum Verständnis der Programme anderer Entwickler, muß an dieser Stelle erwähnt werden, daß das Schlüsselwort int im Zusammenhang mit anderen Schlüsselwörtern, wie unsigned, short, const, etc. entfallen
kann. Z.B. kann anstelle von unsigned int kurz unsigned stehen. Diese Kurznotation wird von uns im folgenden nicht verwendet werden.
4
Literalkonstanten
In Abschnitt 2.2 wurde erklärt, daß die Symbolfolge, aus der sich
ein C++-Programm zusammensetzt, Literalkonstanten enthalten kann.
Diese beschreiben einen Wert, der sich während der Laufzeit des Programms nicht ändern kann. Sie heißen Literalkonstanten, weil ihr Wert
bereits durch die Schreibweise der Konstanten ausgedrückt wird. Jede
Literalkonstante hat einen zugehörigen Datentyp. Entsprechend den vordefinierten' Datentypen gibt es ganzzahlige Konstanten und Zeichenkonstanten sowie Gleitpunktkonstanten. Zur einfachen Ausgabe mehrerer
Zeichen stehen darüber hinaus Zeichenketten zur Verfügung. Der Compiler erkennt nicht nur den Wert sondern auch den Typ einer Literalkonstanten jeweils ohne besondere Deklaration.
4.1
Ganzzahlige Konstanten
Zur Darstellung ganzzahliger Konstanten kann das Dezimal-, Oktal- oder Hexadezimalsystem benutzt werden.
In der Dezimaldarstellung besteht eine ganzzahlige Konstante aus einer Ziffernfolge,
die nicht mit 0 beginnen darf. Liegt ihr Wert im Wertebereich int, so hat sie den
Typ int, anderenfalls den Typ lang int, bzw. unsigned lang int. (Ihr Typ ist
somit maschinen- und implementationsabhängig.)
Beginnt eine ganzzahlige Konstante mit der Ziffer 0, so wird sie als Oktalzahl interpretiert, sie muß also aus Oktalziffern bestehen; beginnt die Konstante mit Ox oder
OX, wird sie als Hexadezimalzahl interpretiert und die nachfolgenden Ziffern müssen
Hexadezimalziffern sein:
OktalzijJer: eins von
o 1 2 3 4 5 6 7
ZijJer: eins von
OktalzijJer 8 9
HexadezimalzijJer: eins von
ZijJer a A b B c C d D e E f
F
Je nach Größe ihres Werts hat die Konstante den Typ int, unsigned int, lang
Herunterladen