You are on page 1of 69

Das C++ Kompendium

INHALTSVERZEICHNIS

1. DATENTYPEN ........................................................................................................................................................ 5
1.1 GANZZAHLIGE DATENTYPEN ...................................................................................................................... 5
1.2 GLEITKOMMATYPEN .................................................................................................................................... 5
1.3 KONSTANTEN .............................................................................................................................................. 5
1.4 VARIABLEN ................................................................................................................................................. 6
1.5 EIGENE TYPDEFINITIONEN ........................................................................................................................... 7
1.6 AUFZÄHLUNGSTYPEN .................................................................................................................................. 7
1.7 KOMMENTARE ............................................................................................................................................. 8
2. EIN- UND AUSGABE ........................................................................................................................................ 9
2.1 DATENSTROMAUSGABE MIT „COUT“ ........................................................................................................... 9
2.2 KONVENTIONELLE AUSGABE ..................................................................................................................... 11
2.3 DATENSTROM-EINGABE MIT „CIN“ ............................................................................................................ 14
2.4 KONVENTIONELLE EINGABE ...................................................................................................................... 15
3. OPERATOREN ................................................................................................................................................ 18
3.1 VERGLEICHSOPERATOREN ......................................................................................................................... 18
3.2 LOGISCHE OPERATOREN ............................................................................................................................ 19
3.3 BITOPERATOREN ........................................................................................................................................ 20
3.4 ZUWEISUNGSOPERATOREN ........................................................................................................................ 21
3.5 INKREMENT UND DEKREMENT ................................................................................................................... 22
3.6 BEDINGUNGSOPERATOR ............................................................................................................................ 22
3.7 SEQUENZ-, SIZEOF-, ADRESSOPERATOR UND KLAMMERN ......................................................................... 22
3.8 TYPUMWANDLUNGEN ................................................................................................................................ 23
4. KONTROLLSTRUKTUREN ......................................................................................................................... 25
4.1 AUSWAHLANWEISUNGEN .......................................................................................................................... 25
4.2 WIEDERHOLUNGSANWEISUNGEN ODER LOOPS: „WHILE“, „FOR“, UND „DO WHILE“ ................................... 26
4.3 SPRUNGANWEISUNGEN .............................................................................................................................. 28
5. ZEIGER UND REFERENZEN ....................................................................................................................... 29
5.1 ZEIGER....................................................................................................................................................... 29
5.2 REFERENZEN.............................................................................................................................................. 31
6. ARRAYS ........................................................................................................................................................... 32
6.1 EINDIMENSIONALE ARRAYS ...................................................................................................................... 32
6.2 MEHRDIMENSIONALE ARRAYS .................................................................................................................. 34
6.3 ZEIGERARRAYS .......................................................................................................................................... 35

C++ KOMPENDIUM 2
Rev. 1.01

7. SPEICHERVERWALTUNG .......................................................................................................................... 36
7.1 SPEICHERVERWALTUNG MIT „NEW“ .......................................................................................................... 36
7.2 SPEICHERFREIGABE MIT “DELETE” ............................................................................................................ 37
7.3 ZEIGER AUF ZEIGER ................................................................................................................................... 37
7.4 DYNAMISCHE SPEICHERVERWALTUNG ...................................................................................................... 38
8. FUNKTIONEN ................................................................................................................................................. 39
8.1 DEFINITION UND AUFRUF .......................................................................................................................... 39
8.2 DEKLARATION VON FUNKTIONEN (PROTOTYPEN) ..................................................................................... 39
8.3 GÜLTIGKEITSBEREICHE ............................................................................................................................. 39
8.4 LEBENSDAUER VON VARIABLEN................................................................................................................ 40
8.5 RÜCKGABEWERTE: DIE “RETURN”-ANWEISUNG ........................................................................................ 40
8.6 PARAMETER ............................................................................................................................................... 41
8.7 FUNKTIONSNAMEN ÜBERLADEN ................................................................................................................ 42
8.8 DIE FUNKTION “MAIN” .............................................................................................................................. 42
8.9 INLINE-FUNKTIONEN ................................................................................................................................. 43
8.10 ZEIGER AUF FUNKTIONEN .......................................................................................................................... 43
9. KLASSEN ......................................................................................................................................................... 44
9.1 DEFINITION VON KLASSEN ........................................................................................................................ 44
9.2 OBJEKTE EINER KLASSE............................................................................................................................. 45
9.3 INITIALISIERUNG UND KONSTRUNKTION VON OBJEKTEN .......................................................................... 47
9.4 KONSTANTE/STATISCHE OBJEKTE ............................................................................................................. 49
9.5 FRIEND-FUNKTIONEN UND FRIEND-KLASSEN ............................................................................................ 50
9.6 SPEZIELLE K LASSEN .................................................................................................................................. 51
10. ABGELEITETE KLASSEN ............................................................................................................................... 52
10.1 MIT “PUBLIC” ABGELEITETE KLASSEN....................................................................................................... 52
10.2 MIT “PROTECTED“ ABGELEITE KLASSEN ................................................................................................... 52
10.3 MIT “PRIVATE” ABGELEITETE KLASSEN..................................................................................................... 53
10.4 REDEFINITION VON ZUGRIFFSRECHTEN/KONVERTIERUNG......................................................................... 53
10.5 NICHTVERERBBARE KLASSENELEMENTE ................................................................................................... 54
10.6 VIRTUELLE FUNKTIONEN ........................................................................................................................... 54
10.7 ABSTRAKTE KLASSEN/REIN VIRTUELLE FUNKTIONEN ............................................................................... 55
10.8 MEHRFACHVERERBUNG ............................................................................................................................. 55
11. OPERATORFUNKTIONEN .............................................................................................................................. 56
11.1 OPERATORFUNKTIONEN FÜR UNÄRE OPERATOREN ................................................................................... 56
11.2 OPERATORFUNKTIONEN FÜR BINÄRE OPERATOREN .................................................................................. 56
11.3 DER ZUWEISUNGSOPERATOR “ = ” ............................................................................................................ 57
11.2 DER INDEX-OPERATOR “ [ ] “ .................................................................................................................... 57
11.3 DER FUNKTIONSAUFRUF-OPERATOR “ ( ) “ ............................................................................................... 58
11.4 DER PFEILOPERATOR “ -> “ ....................................................................................................................... 58
11.5 DIE OPERATOREN NEW UND DELETE ......................................................................................................... 58
11.6 DER CAST-OPERATOR/KONVERTIERUNGSOPERATOREN............................................................................ 59
12. STREAMS ............................................................................................................................................................ 60
12.1 ALLGEMEINE EIN- UND AUSGABE.............................................................................................................. 60
12.2 EIN- UND AUSGABE VON DATEN ................................................................................................................ 61
12.3 EIN- UND AUSGABEOPERATIONEN MIT SPEICHERBEREICHEN..................................................................... 63
13. SPRACHERWEITERUNGEN ........................................................................................................................... 65

C++ KOMPENDIUM 3
Rev. 1.01

Jedoch sind Fehler nicht völlig auszuschließen. Sie werden deshalb ohne Rücksicht auf die gegenwärtige Patent. 1. Marken.Allgemeine Hinweise: Die in diesem Dokument angegebenen Verfahren sind zu Amateur. http://cplusplus. C++ KOMPENDIUM 4 Rev.de. zurück zu weisen.oder patentrechtlichem Schutz.und Lernzwecken bestimmt. Der Autor ist weiterhin für jede Mitteilung von Fehlern dankbar. jegliche Haftungsansprüche oder juristische Verantwortung für Folgen. „Das C++ Kompendium“. Die angegeben Verfahren wurden mit großer Sorgfalt zusammengestellt. © Copyright 1998 – 2007. Der Verfasser sieht sich demnach gezwungen.oder Copyrightlage mitgeteilt.01 . Die Markennamen der in diesem Dokument erwähnten Firmen unterliegen generell Warenzeichen-. Nathan Bailey.opensourcebook. die aus fehlerhaften Angaben resultieren.

dezimale (1 bis 9. o long besitzt Werte von 0 bis 232 o bool kann die zwei Werte „wahr“ oder „falsch“ annehmen.und Zeichenketten-Konstanten.01 . double. o float: zwischen 4 Bytes und double: o double: zwischen float und long double. deren Wert unveränderlich ist. stets mit 0 beginnend). aber kleiner als „int“) hat den Speicherbereich von 2 Bytes. gewöhnlich 8 Bytes. o int: (größer als short. o signed char (mit vorzeichen). besitzt 2 Bytes für short oder 4 Bytes für long. C++ KOMPENDIUM 5 Rev. Gleitkomma-. z. bzw. long int. und long double. int. aber kleiner als long).3 Konstanten • Konstanten: Daten. Zeichen. keine führende Null). Die Unterscheidung zwischen signed und unsigned char wird ab Beträgen über 127 wichtig! o short (größer als „char“. läuft im ASCII-Code von -128 bis 127. o long double: gewöhnlich 10 oder 12 Bytes 1. und bool. aber ohne Namen) und benannte. short int. oder hexadezimale (Präfix „0x“ oder „0X“). long int und int sind jeweils äquivalent • Benutze „signed“ und „unsigned“ für mit oder ohne Vorzeichen (wenn eine Angabe ohne Spezifikation des Vorzeichens erfolgt. 1. Zeichen.  Ganzzahlige: oktale (0 bis 7. char a = 65 = 01000001 = 1byte = 8bit. Datentypen Ganzzahlige Datentypen • Ganzzahlige Datentypen sind: char. dann wird automatisch „signed“ angenommen – also ist z.B. „signed short“ dasselbe wie „short“) o char: zur Speicherung von Zahlen bzw. 1. „0“. Beachte: „signed char“ nicht unbedingt gleich „char“! o unsigned char: Kann die Werte von 0 bis 255 im ASCII-Code annehmen. o unbenannte Konstanten: Dazu zählen Ganzzahlige. Unterscheidung in unbenannte (mit Wert und Typ. gewöhnlich im ASCII-Code von 0 bis 255. 1. „1“ bzw. • Short int und int.B.2 Gleitkommatypen • Gleitkommatypen sind: float.

o Gleitkomma-konstanten: sind wahlweise mit oder ohne Vorkommateil/Nachkommateil.“ o Ausgabe der Speicher-Adresse der Variable „a“ beispielsweise mittels „cout << &a. Sie haben den Typ „char“.B. beispielsweise durch C++ KOMPENDIUM 6 Rev.  Zahlenwerte sind jeweils längenabhängig mit „int“.4 Variablen • Variablen sind Daten. „long“.“ . o.46e-1. o Variablen besitzen vier Merkmale: Wert. für Hochkommata also \’’. „l“ (long double) andersartig gekennzeichnet.  Im Speicher wird jeder String „unsichtbar“ mit \0 beendet. 1. und in der letzen Zeile mit . Adresse (Lokalisation im Speicher). Der Backslash maskiert nicht darstellbare Zeichen für Compiler – auch der Backslash selbst muss maskiert werden! Weitere Beispiele für Escape-Sequenzen sind:  Tabulator: \t  Signalton: \a  Zeilenvorschub: \n  Seitenvorschub: \f o Stringkonstanten: werden eingebettet in „“ (deshalb muss „ oder “ mit einem Backslash maskiert werden). abschließen. ein Wert zugewiesen. „double x.“ o Initialisierung: mittels der Initialisierung wird der Variablen ein Wert zugeweisen. und ihren Namen. Exponent wird mit „e“ oder „E“ bezeichnet: z. deren Wert Veränderungen unterliegen kann.“ Sie sind grundsätzlich vom Typ double. z. außer explizit durch „f“ (float) oder „L“ bzw. „0. Mit den Suffixen „l“ (long) oder „u“ (unsigned int/long) ist der Typ explizit festlegbar. y. also beispielsweise mit const int x = 1. o Escape-Sequenzen: beispielsweise sind Hochkommata nicht darstellbar. „unsinged int“. oder mit \ . außer durch Voranstellung von \. z. 1.  Stringkonstanten zu verketten geschieht über mehrere Zeilen mit „“. darstellbar. eingebunden.B. In jeder Zeile und mit . Typ.Ä. o Benannte Konstanten werden mit der Syntax const datentyp name_der_konstante = init_Wert.01 . o Zeichenkonstanten: werden in Hochkommata angegeben. o Sie werden mit folgender Syntax eingebunden: „typ name.

• enum-Variable kann nur Werte aus dem Wertebereich ihres Aufzählungstyps annehmen (z. Beispielsweise definiert enum colorA {blau. „typedef unsigned long ulong.01 .“ vereinbart „Matrix“ als Synonym für „int [4][4]. z. Sie dient zur Reservierung von Speicher für den angegeben Datentyp.“ 1.“ gleichbedeutend mit „int m [4][4]. gelb}farbe. C++ KOMPENDIUM 7 Rev.“ definiert „ulong“ als alternative Typbezeichnung von „usigned long“.B. symb_konst2.) • Die Paramter „symb_konst“ bekommen Zahlenwerte von 0 an aufsteigend zugeteilt.B. rot. Möglich ist auch die eigene Definition mit „= x“ (erster nachfolgender Wert bekommt x+1 zugewiesen). sie findet nur einmal bei der Definition am Anfang statt. Allerdings geschieht keine implizite Konvertierung von Aufzählungstypen in „int“. variable2. einen Datentyp „colorA“ mit dem Wertebereich „blau. • Anderes Beispiel: „typedef int Matrix [4][4]. oder double x = 2. des Typs „int“. int a = 1.“ Nun ist „Matrix m. sind zulässig.6 Aufzählungstypen • Ein Aufzählungstyp ist ein ganzzahliger Datentyp. z. Der Aufruf geschieht gemäß der Syntax: enum [name_aufzählungstyp] { symb_konst1. rot. … symb_konst } [variable1. colorA farbe = blau. 1.5 Eigene Typdefinitionen • Eigene Typdefinitionen sind mittels folgender Syntax möglich: „typedef definition“. gelb“ und vereinbart eine Variable mit dem Namen „farbe“ des Typs „colorA“.B. … ]. diese ist nur explizit erzwingbar. 1. o Eine Initialisierung ist aber im Vergleich zu Zuweisung „a=1“ etwas grundsätzlich Anderes. • Zuweisungen von enum-Variablen an Variablen. der mittels des Schlüsselwortes „enum“ aufgerufen wird.

1. die nicht zum eigentlichen Programm gehören. 1.01 . Beispiel: quellcode // Kommentar einzeilig oder quellcode /* Kommentar mehrzeilig */ Allerdings ist die Schachtelung eines Kommentars quellcode /* Diese Form */ ist /* nicht erlaubt */ nicht möglich. oder „/*“ zu beginnen und mit „*/“ zu beenden. sind entweder mit „//“ (einzeilig) anzugeben. C++ KOMPENDIUM 8 Rev. also Erläuterungen im Quellcode. wobei man sie mit „\“ auf die nächste Zeile erweitern kann.7 Kommentare • Kommentare.

• Formatierung: „cout“ gibt Gleitkommawerte nur mit max. wenn zum Beispiel vorher mit char a = ’A’. • Verkettung des Transferoperators: statt cout << x. oder cout << x << y. 2. o Für die Formatierung existieren zwei Gruppen von Funktionen in der I/O- Bibliothek: Sreams (s. 1. Kap. ist ebenso cout << x << y. sondern I/O- Funktionen aus der Ein. Zum Beispiel gibt es für hexadezimale oder oktale Ausgabearten Funktionen (die ohne Funktionsklammern geschrieben werden!) wie etwa „hex“ oder „oct“: z. 12) und Manipulatoren.und Ausgabebibliothek verwendet (auch „I/0-Stream library“ oder „Stream I/O-Bibliothek“ genannt). sechs Stellen aus. den Wert A aus.B cout << hex << 123. Datenstromausgabe mit „cout“ • Syntax: cout << a. o Achtung: Hexadezimaler Anzeigemodus bleibt auch danach bestehen! C++ KOMPENDIUM 9 Rev. möglich. cout << y. • Manipulatoren existieren in großer Zahl zur Modifikation der Ausgabe.01 . der Wert von a definiert wurde.und Ausgabe Zur Ein-und Ausgabe werden nicht unmittelbare Sprachelemente von C++. gibt cout << a. Ein.

gibt „0X7B“ aus. die Mitausgabe eines Zahlensystem-Indikator.und sechs Nachkommastellen).“ setzt Ausgabe wieder auf dezimal zurück. o setiosflags(Flag_Wert): „setiosflags(128L)“ bewirkt z. wird die Zahl immer als fixed ausgegeben.456. Zehnerexponent (e±DDD (mit drei Dezimal-stellen))) o Wenn der Exponent zwischen -4 und 6 liegt. Beispiel: cout << hex << setiosflags (128L) << setiosflags(512L) << 123.23457 (gerundet) und mit fixed 1. bezieht sich auf jeweilige Zeile.“ angegeben.B. Parameter right = 4. gibt 1. cout << setiosflags(scientific) << 123.234567 aus.00. o Standardformat: im Standardformat gibt es insgesamt sechs Ausgabestellen.B. o Erzwinge größere Breite des Ausgabefeldes mit „setw(mindestbreite)“.put(Zeichen). Parameter internal = 8) o Unformatierte Ausgabe: durch „put“. o Parameter für setioflags: Zweierpotenzen von 20 bis 214. „resetioflags(128L)“.01 . Bei „fixed“ sind es sechs Nachkommastellen.23457e+006 aus. Erst beispielsweise ein „cout << dec.B.h“ im Programmkopf eingeschlossen werden. z. o Zwei Formate für Gleitkommazahlen: „fixed“ (normal mit vor. Leerzeichen werden vorangestellt. o Erzwinge Stellenanzahl mit Manipulator „setprecision(stellenanzahl)“ (setprecision mit „iomanip. B. bzw. „setiosflags(512L)“ bewirkt Großbuchstaben bei hex- Zahlen. „setiosflags(left)“ (Parameter left = 2. Nachkommastellen. Mit resetiosflags(scientific) kann man dieses wieder rückgängig machen. gibt mit im Standardmodus 1. „setiosflags“ muss mit Include-Datei „iomanip.00“ würde beispielsweise nur „123“ ausgegeben) mit cout << setiosflags(showpoint) << 123.B.234567. cout << setw(12) << setfill (’#’) << 99 ergibt #######99 o Bestimme Bündigkeit (Ort an dem die Füllzeichen gesetzt werden) mit z. o Erzwinge beispielsweise eine scientific-Ausgabe mit setiosflags: z. setiosflags (0x400) in hex. o Rücksetzung mit „resetioflags“. C++ KOMPENDIUM 10 Rev. o Erzwinge beispielsweise eine Nachkomma-Nullstellen-Anzeige (denn „cout <<123. alle vom Typ long. das eine Methode von cout ist. 1. Sie wird mit der Syntax „cout. setprecision benötigt Int- Parameter) o Erzwinge Vorzeichenausgabe mit setiosflags(1024).h“ in Programm einbinden. o Anderes Füllzeichen für Leerstellen von setw: mit „setfill(zeichen)“. z. Daraus folgt: cout << 1. o Benannte Konstanten können als feste Parameterwerte für setiosflags definiert werden. scientific (eine Vorkommastelle.

• Der Formatstring enthält gewöhnliche Zeichenkette und Formatangaben • Die Formatangabe besteht aus „%“ und einem Kennbuchstaben. Der int-Wert wird mittels %d in den C++ KOMPENDIUM 11 Rev. [ parameter2. 1. printf besitzt hier zwei Parameter. Hier eine kurze Übersicht über alle Manipulatoren: 0x0001 Zwischenräume überspringen 0x0002 Linksbündig 0x0004 Rechtsbündig 0x0008 Internal 0x0010 Dezimal setzen 0x0020 Oktal setzen 0x0040 Hexadezimal setzen 0x0080 Zahlenbasis anzeigen 0x0100 Dezimalpunkt anzeigen 0x0200 Großbuchstaben (hex/Exponent) 0x0400 Pluszeichen anzeigen 0x0800 Scientific-Format 0x1000 Fixed-Format 0x2000 IO-Puffer leeren 0x4000 IO-Puffer leeren Dec Dezimal Oct Oktal Hex Hexadezimal Setprecision(int stellenzahl) Gleitkomma-Genauigkeit Setw(int mindestbreit) Feldbreite Setfill(int zeichen) Füllzeichen Setiosflags(long flag) IO-Flags setzten Resetioflags(long lfag) IO-Flags zurücksetzen Konventionelle Ausgabe Für die konventionelle Ausgabe ist es nötig.h)“ einzuschließen. parameter3. Beispiel: printf(„die Zahl %d ist dreistellig“. • Formatierte Ausgabe: folgt der Syntax printf(formatstring. den notwendigen Formatstring und den int-Wert 123. am Programmanfang die Include-Datei „stdio.h“ mittels „#include(stdio. Zu beachten ist die Trennung des Formatstrings von den Parametern mit einem Komma. Dabei ist mindestens der Parameter „formatstring“ notwendig. „%d“ als Formatangabe für ganzzahligen Dezimalwert. …]). der das aktuell gebrauchte Format anzeigt.01 . führt zur Ausgabe „Die Zahl 123 ist dreistellig“. z.B. 123).

Zur Verwendung anderer Füllzeichen. wird die entsprechende Zahlenbasis mit angezeigt (z. es geschieht als eine automatische Erweiterung auf vier. 1. %li Dezimale Zahl Typ long %o Oktale Zahl Typ int %ho Oktale Zahl Typ short %lo Oktale Zahl Typ long % %x.B. String „123“ konvertiert. %hi Dezimale Zahl Typ short %ld. gibt printf(„%2d\n“. gibt „00001234“ aus. führt „printf(„%#x“.B. %X (Großbuchstaben bei der Ausgabe) Hexadezimale Zahl Typ int %hx. Mit %d sind auch mehrere Zahlenwerte in einen String einordbar. Z.01 . 1234). %lX (Großbuchstaben bei der Ausgabe) Hexadezimale Zahl Typ long % %u. Hier eine Anführung aller Formatangaben: Formatangabe Ausgabewert %d Dezimale Zahl typ int %i Dezimale Zahl Typ int %hd. oder auch beispielsweise aus einem Zeilenvorschub \n bestehen. %hX (Großbuchstaben bei der Ausgabe) Hexadezimale Zahl Typ short %lx. 123). o Maskiere das %-Zeichen mit weiteren angestellten %-Zeichen o Formatstrings können in Teilstrings mit mehreren Zeilen. Dezimale Zahl vom Typ unsigned int %hu Dezimale Zahl vom Typ unsigned short %lu Dezimale Zahl vom Typ unsigned long %c Zeichen o Wenn „#“ zwischen „%“ und Kennbuchstaben eingefügt wird. C++ KOMPENDIUM 12 Rev. 1234). 1234). mit zwei Feldern nur die Hälfte der benötigten an. die nicht benötigten Felder werden mit Leerzeichen vorangestellt. printf(„%8d“. stelle man die Füllzeichen der Feldzahlangabe voran: printf(„%08d“. gibt die doppelte Breite an.“ zu „0x7b“ als Ausgabe) o Feldbreite und Füllzeichen: variiere Feldbreite mit der dem %-Zeichen nachgestellten Zahl.

340000“ (mit Plus-Zeichen). g oder e ein L setzt. (Ausgabeziffernanzahl-Angabe auch ohne Angabe zur Breite des Feldes möglich)  Mit Anzahl der Ausgabeziffern und Breite des Feldes lässt sich z. o Variation der Feldbreite auch mit * und zusätzlicher Parameterangabe möglich.zahl Typ float oder double %e. erfolgt eine scientific-Darstellung.B. erhält man „0001.2345.zahl Typ long double Erläuterungen: o %f entspricht dem Format fixed bei Stream-Ausgaben (sechs Nachkommastellen). 1.6d“. %E Gleitk. %LG Gleitk. o Beispiele:  Mit printf(„%+f“. o %e entspricht dem scientific-Format. 8.B. für Breite des Feldes (hier 8) und Anzahl der Ziffern (hier 6): „printf(„AAA\n%8. 1. o Wenn man vor f.zahl Typ long double %Lg.2345). Hier eine Übersicht über die Formatangaben für Gleitkommawerte: %f Gleitk. erhält man Gleitkommawerte vom Typ long double. 1. ergibt die Ausgabe 1.“ gibt „AAA000017“ aus. 1234).  Mit printf(„%08g“.3f\n%10.zahl Typ float oder double %LF Gleitk. eine Tabelle ausgeben  Bündigkeit: mit – Zeichen zwischen % und Feldbreitenangabe entsteht Linksbündigkeit.235 C++ KOMPENDIUM 13 Rev. 12.01 .234).6f“. %G Gleitk. erhält man die Ausgabe „+12. z.zahl Typ long double %Le. %LE Gleitk. 17). 1. „printf(„%*d“.zahl Typ float oder double %g.34).“ für Feldbreite 8 mit 4 vorangestellten Leerzeichen  Anzahl der Ausgabeziffern: z.B.234“ (Füllzeichen sind Nullen) o Genauigkeit: printf(„%5. o Wenn bei %g der Exponent kleiner ist als -4 oder größer als die Stellenanzahl.

234500 (zwei führende Leerzeichen wegen 10 Stellen und zwei anschließende Nullen wegen sechs Nachkommastellen) o mit 0: erreiche so viele Ausgabestellen für Gleitkommzahlen wie nötig. &i). die das long-Format überschreiten) o Formatangaben für Strings mit %s: z. (hier wird wegen maximal 3 Nachkommastellen gerundet) und die Ausgabe 1. o Formatangaben für Adresswerte mit %p und %n: z. beispielsweise ergibt printf(„%0Lf“. Beispielsweise liest int = i. aber ohne Nachkommastellen und Dezimalpunkt . nach Definition int = i. 123456789. Syntax: „putchar(Zeichen)“.123).B.B. die Adresse hexadezimal bzw. die Adresse von i ausgeben oder mit printf(„%X %d“. &i. C++ KOMPENDIUM 14 Rev. &i).B. die Ausgabe 123456789 (wenn man z. größere ganzzahlige Werte darstellen will. dezimal ausgeben o Unformatierte Ausgabe: Gegenstück zur Stream-Funktion „put“ ist „putchar“. 1. „printf(„%-12s“.01 . Datenstrom-Eingabe mit „cin“ • Syntax des Befehls cin: cin >> Programmvariable. mittels printf(„%p“. String)“ resultiert in einer linksbündigen Ausgabe „String“ mit sechs nachfolgenden Leerezeichen.

o Verkettung: wie bei „cout“ ist auch bei „cin“ eine Verkettung möglich.get mit Parameter: „char c. oct und hex. c = cin. Trennung bei der Eingabe erfolgt durch Leerzeichen oder Zeilenvorschub.01 . Konventionelle Eingabe Für die konventionelle Eingabe ist die Datei „stdio. würde „16“ ausgegeben werden.get sind äquivalent.get( ).“ liest ein Zeichen ein und speichert es in c.h>.h“ aus der Standardbibliothek am Programmkopf einzuschließen mittels „#include <stdio. oder mit Manipulatoren dec. adresse2. 1. cin >> hex >> a >> oct >> b. z. …]). • Formatierte Eingabe: Gegenstück zu „printf“ ist „scanf“.B. d: cin >> i >> c >> d. und cin >> i. z.B.get(c).get() (paramterlos). für Eingabe von Werten von i. Beispiel: „char c. [adresse1. o Paramterabhängige und –unabhängige Anwendung von cin. o cin. o Formatierung: Hexadezimale/Oktale Eingabe auf cin >> a >> b.“. einen Wert in die Variable i ein. cin. c. Mit cout << a << „ “ << b. o Unformatierte Ausgabe mit get: Syntax: cin.“ liest ein Zeichen und speichert es in c. das mit folgender Syntax verwendet wird: scanf( formatstring. mit 0x10 und 020 möglich was beides zur Speicherung von „16“ führt. C++ KOMPENDIUM 15 Rev.

zahl Typ long double %e. %X (Großbuchstaben bei der Ausgabe) Hexadezimale Zahl Typ int %hx.zahl Typ float (scientific) %ie. Beispielsweise definiert man int x. 1.zahl Typ float %lf Gleitk. %LE Gleitk. Dezimale Zahl vom Typ unsigned int %hu Dezimale Zahl vom Typ unsigned short %lu Dezimale Zahl vom Typ unsigned long %c Zeichen Und eine Tabelle für Formatangaben für Gleitkommawerte: Formatangabe Ausgabewert %f Gleitk. %li Dezimale Zahl Typ long % %o Oktale Zahl Typ int %ho Oktale Zahl Typ short %lo Oktale Zahl Typ long % %x. und liest dann mittels scanf(„%d“.zahl Typ double % Lf Gleitk. %hi Dezimale Zahl Typ short %ld. %G Gleitk.zahl Typ long double (scientific) %g.zahl Typ long double (scient/fix) Erläuterungen und Beispiele: C++ KOMPENDIUM 16 Rev. Hier eine Übersicht über alle möglichen Formatangaben: Formatangabe Ausgabewert %d Dezimale Zahl typ int %i Dezimale Zahl Typ int %hd.zahl Typ double (scientific) %le. %IE Gleitk. %lG Gleitk. %hX (Großbuchstaben bei der Ausgabe) Hexadezimale Zahl Typ short %lx. &x).01 .zahl Typ double (scient/fix) %Lg. %lX (Großbuchstaben bei der Ausgabe) Hexadezimale Zahl Typ long % %u. %E Gleitk. %LG Gleitk. einen Integer-Wert ein und speichert diesen in x.zahl Typ float (scient/fix) %lg.

C++ KOMPENDIUM 17 Rev. was 1 45 als Ausgabe bewirkt. &mins). liest ein Zeichen ein und speichert es in c. &scount). Vorsicht! o Konsoleneingabe (Direktes Lesen von der Tastatur ohne Pufferrückstände. nach „int hours. aber nur der erste und dritte berücksichtigt.“ können reguläre Zeichen mittels „scanf(„%d:%d“. ohne Bildschirmanzeige) mit „getch“ und „getche“: diese beiden Funktionen benötigen den Einschluss der Header-Datei „conio. c = getchar. und scanf(„1%d %2d“. &entry. 1. o Auch reguläre Zeichen sind mit scanf einlesbar: z.01 . &field1. o Eingabezeichen zählen mit „%n“ bis zu „%n“ mittels „int scount“. eine Eingabe von 145 machen. &j).“ eingelesen werden.B.h“ in das Programm. • Unformatierte Eingabe: getchar( ). Z. printf(„Datensatz eingeben: “). &hours. o Feldbreite: beispielsweise nach int i. &i. zwar drei Eingabewerte gelesen. so lässt sich die Anzahl der eingelesenen Zeichen speichern mittels „scanf(„%ld%n. int field2. o %-Zeichen muss mit %-Zeichen maskiert werden. werden mittels int field1. scanf(„%d %*d %d“. mins.B. j. &field3). o Bei mehreren eingegebenen Zeichen: Puffer wird nicht geleert.“ o Eingabewerte überspringen mit „*“: z.B.

Hier eine Übersicht über einige Operatoren und deren Assoziativität: Operator Bedeutung Priorität Assoziativität + Unäres Plus 15 Rechts nach links . • Für unäre Operatoren (Priorität 15). Hier eine Übersicht über alle binären Operatoren Operator Bedeutung Priorität Assoziativität == Gleich 9 Links nach rechts != Ungleich 9 Links nach rechts > Größer 10 Links nach rechts >= Größer/gleich 10 Links nach rechts < Kleiner 10 Links nach rechts <= Kleiner/gleich 10 Links nach rechts C++ KOMPENDIUM 18 Rev.h. Unäres Minus 15 Rechts nach links * Multiplikation 13 Links nach rechts / Division 13 Links nach rechts % Divisionsrest 13 Links nach rechts + Addition (binäres Plus) 12 Links nach rechts . 1.01 .B. • Operatoren kommen in 17 verschiedenen Prioritätsstufen vor. wie z. Zuweisungsoperatoren (Priorität 2) und für den ternären Bedienungsoperator geht die Assoziativität (d. Operatoren mit einem Operanden werden „unär“. solche mit zwei Operanden „binär“. • Generell kann man mittels Klammersetzung die Prioritäten umgehen. Bei allen übrigen geht sie von links nach rechts. Subtraktion (binäres Minus) 12 Links nach rechts Vergleichsoperatoren • Vergleichsoperatoren sind binäre Operatoren. solche mit drei Operanden „ternär“ genannt. Operatoren mit höheren Prioritätsstufen werden vor anderen mit niedrigeren Prioritätsstufen ausgeführt. die Richtung der Auswertung bei gleichwertigen Operatoren) von rechts nach links. 3. in der Mathematik das Mal-Zeichen Priorität vor dem Pluszeichen hat. Operatoren • Operatoren sind in C++ gleichwertig mit Funktionen.

wenn mindestens einer der Operanden true ist. „3 && 7“. da Transferoperator << höhere Priorität hat! Logische Operatoren • Logische Operatoren sind entweder unär oder binär. • Wert der logischen Ausdrücke ist immer entweder „1“ oder „0“ (true oder false) • Logisches UND: Verknüpfung mit UND (&&) liefert nur dann den Wert 1 (true). Hier eine Übersicht über die logischen Operatoren: Operator Bedeutung Priorität Assoziativität Beispiel ! Logisches 15 Rechts nach !x NICHT (unär) links && Logisches UND 5 Links nach x && y (binär) rechts || Logisches 4 Links nach x || y ODER (binär) rechts • Compilerabhängig stehen auch die Schlüsselwörter „not“ für „!“. 1. „and“ für „&&“ und „or“ für „||“ zur Verfügung. d. sind 3 oder -157 true. „(1 <2) && (3 < 4)“. „1 < 2“. da „!a“ den Wert 1 hat. die zweite liefert „1“. C++ KOMPENDIUM 19 Rev. • Jeder von 0 verschieden Wert ist in C++ als „logisch wahr“ (true) interpretierbar (z.B. „!a>0“ und „!(a>0)“ nicht denselben Wert! Die erste Anweisung liefert „0“. da „a>0“ Wert 0 hat (Negationsoperator hat höhere Priorität (15) als Größenoperator (10)). • Äquivalenzbeziehung: „!a“ liefert unabhängig von a immer denselben Wert wie „a==0“. Die Auswertung vollzieht sich von links nach rechts wie bei UND.h. Beachte: beispielsweise liefern „a=-1. • Logisches NICHT: der unäre Operator NICHT liefert den Wert 1. Wenn der erste Wert mit true schon feststeht. • Ausgabewert aller dieser Operatoren ist entweder „1“ (angewandte Operation besteht) oder 0 (Operation besteht nicht). er ist nur dann falsch.B. cout << (x == y). sie haben einen True/False-Rückgabewert. • Logische Auswertung von binären Operatoren geschieht immer von links nach rechts – Wenn der erste Wert mit false bereits feststeht. • Beachte: Bei z. wenn der Operand den Wert 0 hat und umgekehrt. wird der rechte Wert nicht mehr bestimmt. wenn beide Operanden ungleich Null sind.B. muss rechter Operand geklammert werden.01 .“. Daraus folgt. wenn beide falsch sind. wird der rechte Wert nicht mehr bestimmt. dagegen x*y*0 oder -1+1 beide false). z. • Logisches ODER: für ODER ist ein Ausdruck ist vom Wert 1 (true) nur dann.

Die Bits werden also herausgeschoben. 1. o Bitweises UND: „&“ gibt genau dann ein gesetztes Bit aus. eine explizite Zuweisung ist erforderlich.“ einen binären Code – die erste Bitstelle des Resultats ist gesetzt. ansonsten ist es ungesetzt. wenn beide Ausgangsbits unterschiedliche Werte besitzen. Assoziativität links nach rechts) erreicht.“. wenn mindestens eines der Ausgangsbits gesetzt ist. wenn beide ersten Bitstellen der Ausgangscodes gesetzt sind. Wenn beide nicht gesetzt sind. C++ KOMPENDIUM 20 Rev. • Schiebeoperatoren besitzen zwei ganzzahlige Operanden und verschieben die Bits des linken Operanden um so viele Stellen nach links oder rechts. wie der rechte Operand angibt. nicht aber bei Variablen. und „char Buchstabe2=b. wenn beide Ausgangsbits gesetzt sind. z. o Bitweises ODER: „|“ ist ein exklusives ODER: Das Ergebnisbit ist nur dann gesetzt. verschiebt „12351 << 5“ alle Bits von 12351 um fünf Positionen nach links. Wenn Variablen nach einer Verschiebung einen neuen Ausgabewert besitzen sollen. ist das Ergebnisbit 0. • Bitlogische Operatoren: Operator Bedeutung Operatorsymbol Assoziativität Priorität ~ Bitweises NICHT compl Rechts nach links 15 & Bitweises UND bitand Links nach rechts 8 ^ Exklusives bitweises xor Links nach rechts 7 ODER | Inklusives bitweises bitor Links nach rechts 6 ODER o Bitweises NICHT: „~“ gibt den umgekehrten binären Code einer Zahl aus: aus allen Nullen werden Einsen und umgekehrt oder aus „5“ wird „-5“. ansonsten ist es ungesetzt. mit „>>“ eine Rechtsverschiebung. und ungesetzte Bits auf der anderen Seite ergänzt. durch.“ genügt nicht. „1“ ist ein gesetztes Bit. Eine Änderung des Ausgabewerts erfolgt nur bei Konstanten. Bitoperatoren Bitoperatoren führen logische Verknüpfungen mit jedem einzelnen Bit von ganzzahligen Datenobjekten durch oder verschieben sämtliche Bits eines ganzzahligen Datenobjekts um eine bestimmmte Zahl von Positionen nach links oder rechts („Schiebeoperatoren“). „0“ ist ein ungesetzes.01 . Ein „a << 5. und a = a << 5. o Bitweises ODER: „^“ ist ein sogenanntes nichtexklusives ODER: Ergebnisbit ist 1. Beispielsweise besitzen „char Buchstabe_1=a. führe man beispielsweise int a = 12351.B. o Mit „<<“ wird eine Linkverschiebung (Priorität 11.

• Einfache Zuweisungen geschehen mit “=”.bitw. o Wenn beim Herausschieben der Bits keine 1-bit Stellen.bitw. z.B. 1. also ein Objekt. Nur mit einem Operanden. wird ausschließlich mit Nullen aufgefüllt.B. ebenso ist „a <<=b“ ein kurzes „a = a << b“ (analog für alle anderen Operatoren). sondern nur 0-bit Stellen betroffen sind. aber eine Speicherregion bezeichnen). der ein unsigned-Objekt ist.01 . o Mit „>>“ erfolgt eine Rechtsverschiebung von n Bits aus dem Operanden. eine Variable (oder const-Objekte. aber links wird nicht immer dieselbe Anzahl von Stellen nur mit Nullen aufgefüllt. • Zusammengesetzte Zuweisungen: z. das einen Bereich im Speicher bezeichnet. ist „a += b“ eine Kurzschreibweise für „a = a +b“. o Um Verwechslungen mit dem Transferoperator zu vermeiden. sollten Verschiebungen immer eingeklammert werden. ODER 2 Rechts nach links (Schlüsselwort or_eq) ^= Zuweisung mit exkl. C++ KOMPENDIUM 21 Rev. Hier eine Übersicht über alle Zuweisungsoperatoren: Operator Bedeutung Priorität Assoziativität = Einfache Zuweisung 2 Rechts nach links += Zuweisung mit Addition 2 Rechts nach links -= Zuweisung mit Subtraktion 2 Rechts nach links *= Zuweisung mit Multiplikation 2 Rechts nach links /= Zuweisung mit Division 2 Rechts nach links %= Zuweisung mit Modulo-Operation 2 Rechts nach links <<= Zuweisung mit Linksverschiebung 2 Rechts nach links >>= Zuweisung mit Rechtsverschiebung 2 Rechts nach links &= Zuweisung mit bitweisem UND 2 Rechts nach links (Schlüsselwort and_eq) |= Zuweisung mit inkl. o Wenn keine 1-bit Stellen getroffen werden. Zuweisungsoperatoren • Zuweisungoperatoren sind binäre Operatoren. entspricht eine Verschiebung um n Positionen nach links einer Multiplikation mit 2n. die nicht modifizierbar sind. entspricht die Rechtsverschiebung einer Division durch 2n. ODER 2 Rechts nach links (Schüsselwort xor_eq) • Linker Operand muss ein veränderbarer L-Wert („left value“) sein. Zuweisungsoperatoren verändern also die Variablen und speichern das Ergebnis in die Variable ab.

und Dekrement-Operatoren sind Operatoren mit sogenannten „side effects“. bei „b=a-.oder Post-Notation des Operators nicht von Bedeutung • Bei „int a = 1“.“ Bedingungsoperator • Operator „?“ ist als einziger ternär (Priorität 3. Operator Bedeutung Priorität Assoziativität Beispiel ++ Inkrement 15 Rechts nach x++ (Postfix) links ++x (Präfix) -. ebenso „--a“. wird a++. welchen Wert der gesamte Operator- Ausdruck erhält Beispiel: „Ausdruck1? Ausdruck2 : Ausdruck3. dann wird Ausdruck3 ausgewertet und Gesamtausdruck erhält den Wert von Ausdruck3. da er eine geringe Priorität (3) besitzt. Mit dem Sequenzoperator geschieht eine Zusammenfassung von Anweisungen. b = a). Er wertet eine Bedingung aus. Sizeof-. beispielsweise bei „printf („%d %d“. Hier ist also die Prä. Adressoperator und Klammern • Der Vollständigkeit halber wird hier noch der Sequenzoperator „ . oder wenn die Reihenfolge der Auswertung compilerabhängig ist. “ angeführt. von der es abhängt.(Postfix) links --x (Präfix) • Beispiel: „a++“ erhöht den Wert von a um 1. Assoziativität von rechts nach links). Umgekehrt verringert „a--“ den Wert um 1. wenn er „true“ ist. • Nebeneffekte: Inkrement. „int b“ und „b = a++“ wird nach der Zuweisung inkrementiert bzw. der zweite Operand gar nicht mehr ausgewertet und somit das Inkrement nicht ausgeführt. C++ KOMPENDIUM 22 Rev. „int b“ und „b = ++a“ wird vor der Zuweisung von b inkrementiert bzw. 1. Sequenz-. wenn a den Wert Null hat. dann wird Ausdruck2 ausgewertet und Gesamtausdruck erhält den Wert von Ausdruck2. ebenso „++a“. Inkrement und Dekrement • Der Inkrement-Operator erhöht den Wert eines L-Wertes um 1 (Kurzschreibweise für „a = a +1“ oder „a +=1“). z. bei „b = --a“ wird vor der Zuweisung an b dekrementiert. • Der Bedingungsoperator sollte am besten immer geklammert werden. wenn er „false“ ist. Dekrement 15 Rechts nach x-.“ wird nach der Zuweisung an b dekrementiert. b = 5. ++a.“ • Hierbei ist „Ausdruck1“ die Bedingung des gesamten Ausdrucks.01 . • Bei „int a = 1“.B. Entsprechend erniedrigt der Dekrement-Operator den Wert um 1. denn sie verändern den Wert ihres Operanden (im Gegensatz zu logischen Operatoren) Mögliche Fehlerquellen sollten beachtet werden: Beispielsweise bei „a && b++“ wird.

• Implizite Typumwandlung geschieht es durch sog. bei „int i. sizeof(x)“ gleichwertig mit „char x. unsigned int)-Typen konvertiert. Der Sequenzoperator hat die niedrigste Priorität 1. Konvertierung geht immer auf „das Maximale“. Bei unterschiedlichen Typen müssen sie aneinander angegelichen. sollten Klammern gesetzt werden. • Bei der Konvertierung wird lediglich eine Kopie des Datenwertes erstellt. • Typkonvertierung bei Zuweisungen: Mögliche Datenverluste treten auf. einer „long“. long zu float. • Der Sizeof-Operator ermittelt Größe eines Ausdrucks oder Datentyps. oder long zu short auf. z. Beispielsweise wird bei zwei Operanden. hat Priorität 15. i = d. z. „integral promotion“ oder „usual arithmetic conversions“. Die Ausgabe erfolgt dann ebenfalls im Format „long“. also konvertiert werden. ist die Notation ohne Klammern möglich.01 . Ebenfalls tritt Datenverlust bei float zu int. die Assiozativität ist von rechts nach links.B. und die Assiozativität geht von rechts nach links. double zu float.B. einer „int“.“ gehen die Nachkommastellen verloren. ist „char x. double d = 1.z) (function call) rechts () Objekt-Konstruktion 16 Links nach klasseX (y. der zweite nach „long“ konvertiert. 1. z. bei integral promotion (Ganzzahlerweiterung) werden char oder short-Typen in int (bzw. Er hat Priorität 15. • Der Adress-Operator „&“ ermittelt die Speicheradresse des Operanden und benötigt deshalb einen L-Wert. mit dem Sequenzoperator in eine Zeile gefasst: a++. entweder implizit durch den Compiler oder explizit durch eine Anweisung. o Wert des Gesamtausdrucks ist gleich dem des letzen Operanden.z) (value construction) rechts [] Array-Indizierung 16 Links nach arrayX [y] (subscript) rechts () Explizite 15 Rechts nach (typX) y Typkonvertierung links typX (y) Typumwandlungen • Grundsätzlich benötigen Operatoren Operanden gleichen Typs. Er ist unär. o Wenn der Operand ein Ausdruck ist. sizeof x.B. kleinere werden auf größere Typen umgewandelt. „sizeof(char)“. der alte Wert bleibt erhalten. C++ KOMPENDIUM 23 Rev. wenn größerer in kleineren Typ konvertiert wird. b = 5.“ Wenn der Operand ein Datentyp ist.23. • Klammern kommen in folgenden Varianten und Eigenschaften vor: Operator Bedeutung Priorität Assoziativität Beispiel () Funktionsklammern 16 Links nach funktionX (y.

double. Dekrement Rechts nach links 15 new. Sequenzoperator Links nach rechts C++ KOMPENDIUM 24 Rev. wenn der Typ ein einfacher Datentypname ist z. Minus (binär) Links nach rechts 11 << >> Bit-Verschiebung Links nach rechts 10 < <= > >= Größer(gleich)/Kleiner(gleich) Links nach rechts 9 == != Gleichheit Links nach rechts 8 & Bitweises UND Links nach rechts 7 ^ Bitweises ODER (exklusiv) Links nach rechts 6 | Bitweises ODER (inklusiv) Links nach rechts 5 && Logisches UND Links nach rechts 4 || Logisches ODER Links nach rechts 3 ?: Bedingungsoperator Rechts nach links 2 = += -= *= Zuweisung Rechts nach links /= %= <<= >>= &= ^= |= 1 . • Explizite Typumwandlung geschieht mit Hilfe des cast-Operators „( )“ mit folgender Syntax: „(typ) Ausdruck (herkömmliche Notation)“ oder „typ (Ausdruck) (funktionale Notiation)“. delete Speicherverwaltung Rechts nach links 14 . Ausschlaggebend ist jeweils der Typ des linken Operanden.B. Inkrement. in der berechnet wird. o. Die Funktionale Notation ist aber nur dann anwendbar. -> Komponentenauswahl Links nach rechts 15 () Typkonvertierung Rechts nach links 15 Sizeof Größe in Bytes Rechts nach links 15 & Adress-Ermittlung Rechts nach links 15 * Verweis/Indirektion Rechts nach links 15 ~ Bitweise Negation Rechts nach links 15 ! Logische Negation Rechts nach links 15 + .* ->* Komponentenauswahl Links nach rechts 13 * / % Multiplikation Division Modulo Links nach rechts 12 + . Plus. Minus (unär) Rechts nach links 15 ++ -.01 . long. Plus. Hier eine Übersicht über alle C++ Operatoren: Priorität Operator Bedeutung Assoziativität 17 :: Bereichszugriff (unär) Rechts nach links 17 :: Bereichszugriff (binär) Links nach rechts 16 () Funktionsklammern Links nach rechts 16 () Objektkonstruktion Links nach rechts 16 [] Array-Index Links nach rechts 16 . • Beachte bei Berechnungen und Zuweisung die Arithmetik. 1.Ä.

Auswahlanweisungen. Wenn „ausdruck“ den Wert false hat. wird zur nächsten Zeile nach „if“ übergangen. • if hat die Syntax: „if (ausdruck)“. C++ KOMPENDIUM 25 Rev. da sonst Compiler else Anweisung zum zweiten if rechnet. sollten []-Klammern gesetzt werden. Beispiel: if(ausdruck) anweisung(en)1 else anweisung(en)2 o Sollte „anweisung(en)“ aus mehreren Anweisungen bestehen. dann wird anweisung(en)1 nach „if“ ausgeführt. wird „anweisung(en)“ ausgeführt – wenn nicht. Beispiel: if(ausdruck) { anweisung(en) } o Hat „ausdruck“ den Wert true. • if / else hat die Syntax: „if (ausdruck) … else“. o Schachtelung von if und else ist möglich nach folgendem Schema if else if else o Vorsicht: Wenn beispielsweise die erste Selektionsanweisung eine if else- Anweisung sein soll und dazwischen eine if-Anweisung geschaltet werden soll. o Wenn „ausdruck“ den Wert true hat. Kontrollstrukturen Die Sprache C++ bietet vier verschiedene Varianten von Kontrollstrukturen: Selektionsanweisungen. ist die Klammerung mit „{ }“ zu benutzen. if else und switch angegeben. o Wenn mehrere Anweisungen von if abhängig sein sollen. 1. Auswahlanweisungen • Auswahlanweisungen werden mit den Schlüsselwörtern if. Iterationsanweisungen. und Sprunganweisungen. sollten immer entsprechende Klammern gesetzt werden. Um Irrtümer zu vermeiden. 4. muss die zweite if-Anweisung geklammert werden.01 . dann werden anweisung(en)2 nach „else“ ausgeführt.

o Die Anweisungen werden solange ausgeführt. Dies führt nach Ausführung der anweisung(en) zum Stopp. wie die Auswertung des ausdrucks true ergibt. Deshalb empfiehlt es sich. ausgeführt. gibt int i = 1. auch die der anderen „cases“. while (i < 11) { cout << i << „ “. auch die anderer cases. • switch: „switch“ ermöglicht die Auswahl zwischen beliebig vielen Alternativen Damit ist „switch“ gleichwertig mit geschachteltem „if else“. Wenn eine Übereinstimmung vorliegt. ausgeführt werden. damit nicht alle nachfolgenden Anweisungen. wird die entsprechende anweisung(en).h>“ C++ KOMPENDIUM 26 Rev. 1. } die Zahlen 1 bis 10 aus. Wenn keine vorliegt. werden die Anweisungen nach „default“ ausgeführt – hier anweisung(en)3. hier anweisung(en)1 oder anweisung(en)2 ausgeführt.B. z. werden alle nachfolgenden Anweisungen. o Wenn kein Wert übereinstimmt und keine default-Option vorhanden ist. Wiederholungsanweisungen oder loops: „while“. „switch“ hat die folgende Syntax: „switch(ausdruck)“. wird zur nächsten Zeile nach switch übergegangen. Beispiel: switch(ausdruck) { case konst1: anweisung(en)1 case konst2: anweisung(en)2 … default: anweisung(en)3 } o „ausdruck“ nach switch muss ganzzahlig sein. i++. das mit „#include <conio. und „do while“ • while hat die Syntax „while(ausdruck)“ mit darauf folgenden Anweisungen. Nach der Reihe wird er mit jeder der ebenfalls ganzzahligen Konstanten verglichen („case“). o Beachte: wenn Übereinstimmung vorliegt.01 . Allerdings muss die default-Option nicht zwingend vorhanden sein. wird die Anweisung nach „default“ ausgeführt. „for“. „i“ wird hier als Kontrollvariable bezeichnet o Endlosschleifen sind mit „while“ möglich. jede der mit „case“ bezeichneten Alternativen mit einem „break“ abzuschließen. wobei die Alternativen mit einem vorangestellten „case“ gekennzeichnet werden. Sollte keine der Möglichkeiten von „case“ den Wert true zurückgeben. und sie muss auch nicht unbedingt die letzte sein. Abbruch einer Endlosschleife beispielsweise durch: „kbhit( )“ („Keyboard-Hit“.

„End of File“-Zeichen. 1. werden die „anweisung(en)“ wiederum ausgeführt. sollen Schleifenanweisungen ausgeführt werden: while (!kbhit( )) { anweisung(en) } o Vorsicht bei Endlosschleifen! Sie können zum Absturz des Programms oder des ganzen Betriebssystems führen! Beende eine Schleife durch Eingabe von Strg+Z (sog. Durch Drücken einer beliebigen Taste wird das Programm beendet: if (khbit( )) exit (0). Falls wiederum ein true- Wert ermittelt wird. das im Code mit „EOF“ eingebunden wird). for (i = 2. re_init_wert ) anweisung(en) Beispiel: for (int i = 0. sind diese in { }- Klammern zu setzen. i<100 . o „while“ eignet sich vorzüglich. um eine Pufferentleerung zu erreichen. die durch „for“ ausgeführt werden sollen. bedingung . i < 11. Leere den Puffer beispielsweise mittels „while (cin. da immer „true“ ausgewertet wird. long faculty10 = 1. o Eine fehlende Bedingung führt zu Endlosschleife. berechnet den Wert von 10!. o Beispiel: int i. Danach wird Bedingung für re_init überprüft.01 . am Programmkopf eingeschlossen werden muss). i++) anweisung(en) Bei mehreren Anweisungen. o Beachte: Für die bisherigen Kontrollstrukturen ist kein Semikolon am Ende notwendig • do while hat eine Syntax nach folgendem Schema: do C++ KOMPENDIUM 27 Rev. o Wenn die Bedingung für den init_wert den Wert true hat. i++) faculty10 *=i.get ( ) != ’konstante’) • for wird mit folgender Syntax verwendet: for ( init_wert . o Oder: solange keine Taste gedrückt. werden „anweisung(en)“ ausgeführt.

5.01 . „goto“ hat die Syntax: „goto label. • break hat die einfache Syntax „break. „goto“. Sprunganweisungen Sprung oder Kontrolltransferanweisungen sind: „break“.“ damit wird z. danach abhängig vom Rückgabewert der while-Schleife. • return: siehe Punkt 8. anweisung(en) while (ausdruck). „continue“. eine if-Schleife beendet.“ Ein Label kann beliebig definiert werden. beispielsweise „anfang:“. Mit „continue“ bricht ein einzelner Schleifendurchgang ab und setzt sich mit dem nächsten Durchgang fort. C++ KOMPENDIUM 28 Rev. zu der gesprungen werden soll. • goto: springt an eine mit einem Label gekennzeichnete Stelle. Dabei wird das Label mit der Syntax „label:“ eingeschlossen – es wird einfach vor die Stelle im Code gesetzt. Hier ist ein Semikolon am Ende notwendig! o mit „do while“ werden anweisung(en) auf jeden Fall einmal ausgewertet. • continue: kommt ausschließlich in Wiederholungsanweisungen vor. 1. wenn das Programm an einem gewissen Punkt zu der mit „anfang“ markierten Stelle zurückspringen soll. und „return“.B.

Zeiger und Referenzen Bei Zeigern und Referenzen spricht man von abgeleiteten Datentypen. das die Adresse eines anderen Objektes speichert bzw. o Beispielsweise ist der Adressoperator „&“ ein Zeiger.B. o Zeiger können mittels logischer Operatoren verglichen werden.01 . b. Hier ist „zx“ ist ein Zeiger auf „x“. o Initialisierung: z. short *zs = &a. ersetzt werden. short *zx = &x. da sie in Abhängigkeit zu Daten elementaren Typs stehen. short x. darstellt. Hier wird aus der Adresse des Datenobjekts das Datenobjekt selbst gemacht. der mit der Adresse von x initialisiert wird. 1. 5. die keine elementaren Datentypen sind. • Zeigervariablen haben die Syntax: datentyp_des_verweisobjekts * name_des_zeigers. • Derefernzierte Zeiger: ist short a. Zeiger • Ein Zeiger ist ein Datenobjekt (konstant oder variabel).Zeichen bedeutet soviel wie „ist Zeiger auf“. durch b = *zs . definiert. o Zeiger oder Adresskonstanten verweisen immer auf dieselbe Speicherstelle. kann die Zuweisung b=a. Beispielsweise erhält a mittels „a = 123“ oder „*zs = 123“ den Wert 123. o Mittels neuer Zuweisungen können neue Werte für Zeigervariablen festgelegt werden. C++ KOMPENDIUM 29 Rev. Adressvariablen dagegen auf Adressen verschiedener Objekte. Das * .

wenn z. Jetzt sind allerdings keine Zuweisungen von void* an andere Zeigertypen mehr möglich. z. C++ KOMPENDIUM 30 Rev. double b. o Dadurch kann man. Hier ersetzen die Zeiger die eigentlichen Objekte.B. außer mittels einer expliziten Konvertierung. in die *vz konvertiert wird. Dieser hat die Syntax: „void*“.01 . 1. o Beispiel: int *const p = &a. mittels „cout << *p + *q“ den Wert der Summe von i und k berechnen und anzeigen lassen. muss eine explizite Typangabe erfolgen. erreicht werden kann. void *vz.B. int a. • Ein Konstanter Zeiger verweist nur auf bestimmte Stelle im Speicher mittels des Schlüsselworts „const“ – deshalb muss ein konstanter Zeiger wegen den Definitionsregeln für konstante Objekte initialisiert werden. Dies würde einen Zeiger für beliebige konstante Datenobjekte vom Typ int ergeben!) o Die Zuweisung „*p = 123“ wäre in diesem Beispiel äquivalent zu „a = 123“.B. (nicht: „const int *p = &a“. ist ein generischer Zeiger gefragt. gesetzt werden. ohne die Typangabe vorher festzulegen. mittels *(double*)vz = 1. was z. „void *vp“ kann jetzt sowohl als vz = &a. „*p = &i“ und „*q = &k“ definiert worden sind.B. als auch als vz = &b. Konstante Zeiger kann man nicht einem neuen Objekt zuordnen. • Nullzeiger: unter der Adresse 0 werden nie Daten gespeichert – gewöhnlich wird er nur zur Ausgabe eines Fehlers verwendet. • Generische Zeiger: Falls eine Adresse gespeichert werden soll. o Wenn allerdings dem generischen Zeiger „*vz“ ein Wert zugewiesen werden soll. intpointer = (int*)voidpointer.001. z.

• Referenzen müssen initialisiert werden. C++ KOMPENDIUM 31 Rev. Referenzen Der Zugriff auf ein Datenobjekt kann unter einem anderen Namen geschehen als dem Namen des Objekts selbst. z. int &ref = i. • Beispiel: int i. eine Referenz „ref_a“ auf die int-Konstante „a“ fest. definiert eine Referenz „ref“ auf i. legt const int a = 2.01 . 1. Referenzen haben deshalb auch dieselbe Syntax wie Variabeln: datentyp &referenz_name = ausdruck. • Bei Referenzen auf Konstanten muss der Initialisierungswert nicht unbedingt ein L-Wert sein. und zwar mittels Referenzen. • Zeiger auf Referenzen und Referenzen auf Referenzen sind nicht möglich.B. const int &ref_a = a. weil sie einen konstanten Alias-Namen für das Objekt festlegen – bei Variablen muss der Initialisierungswert ein L-Wert sein.

). Eindimensionale Arrays • Das klassische eindimensionale Array hat die Syntax: typ_der_arrayelemente name_des_arrays [anzahl_der_arrayelemente]. beispielsweise „long tabelle1 [10]“. mittels long tabelle1 [10] = { Wert1. • Die Indizierung der Elemente beginnt bei 0. z.01 . Arrays • Array. Wert2. i < 10 i++) cin >> tabelle1[i]. Für eine Initialisierung größerer Arrays ist ein Loop empfehlenswert. • Initialisierung geschieht z. nicht aber Referenzen oder Funktionen (aber Zeiger auf Funktionen). Zuweisung (tabelle1[0] = 1234.B. oder für die Ausgabe aller Elemente mit einer Schleife int i. bereits bestehenden Array (hier „tabelle0“) kopiert werden sollen: for ( i = 0. 1. …. Klassen oder Aufzählungstypen. • Eingabe: vor allem bei größeren Arrays empfiehlt sich eine Eingabe mit einer Schleife. for ( i = 0. außerdem Zeiger. i < 10 i++) cout << tabelle1[i] << „ “. 6. Das Array heißt hier „tabelle1“. dessen einzelne Bytes zu einer logischen Einheit zusammengefasst werden. nicht bei 1! Im obigen Beispiel läuft deshalb die Indizierung von 0 bis 9. C++ KOMPENDIUM 32 Rev. und besteht aus 10 Elementen des Typs „long“. lassen sich alle üblichen Operationen mit ihnen durchführen. „Feld“ oder „Tabelle“. ist ein zusammenhängender Bereich im Speicher. zu Deutsch „Vektor“. i < 10 i++) tabelle1[i] = tabelle0[i]. z. oder aus einem anderen.B. und nicht wie man zunächst annehmen könnte von 1 bis 10. • Die Elemente von Arrays sind die elementaren Datentypen.B. Wert10 }.) oder Dekretion (tabelle1[1]--. wenn die Array-Werte über Tastatur eingegeben werden sollen: for ( i = 0. • Da die Elemente des Arrays gewöhnliche Variablen sind.

o Indizierte Zeiger: Wird ein Zeigername beispielsweise mit der Anfangsadresse initialisiert. o Die Initialisierung von char-Arrays (also die Erzeugung von Stringvariablen) geschieht entweder mit „char a [] { einzelne Zeichen und \0 in Hochkommata }“ oder kürzer mit char a[anzahl_der_zeichen +1] = „hier_der_string“.“. bis „ENTER“ gedrückt wird.“ ein Array mit \0 als letztem Element anlegt. • Arrays und Zeiger: Der Name eines Arrays ist bereits ein konstanter Zeiger auf den Arrayanfang – der Compiler übersetzt ihn als einen dereferenzierten Zeiger. dann ergibt sich kein Array aus Strings.B. 1. wird im Gegensatz zu anderen Datentypen stets der Inhalt und nicht die Adresse des Arrays ausgegeben (außer natürlich dies geschieht explizit. Wenn das letzte Element nicht „\0“ ist. Sie geschieht beispielsweise mittels while ((array[i] = cin. sondern lediglich ein Array aus Zeichen o Compiler übersetzt allgemein einen jeden String dadurch. Hier eine Übersicht über die Äquivalenzen zwischen Zeiger. kann man mittels des Zeigernamen anstatt des Arraynamen auf das n- te Element des Arrays zugreifen (). dass das letzte Element des Arrays „\0“ ist. a ist dann allerdings eine Variable!) o Zeichenweise Ein/-Ausgabe ist die wohl gebräuchlichste Methode. bei „cout << „Text“. o Arrayname als Zeiger: „&arrayname[0]“ und „arrayname“ sind Zeiger auf die Anfangsadresse des Arrays.get( ) != ENTER) wodurch so lange einen String eingelesen wird. z.B.01 . C++ KOMPENDIUM 33 Rev. „pa“ den Zeiger) &a[0]  A &a[n]  a+n &a[n]  pa+n * &a[n]  &pa[n] * &pa[n]  pa+n * a+n  pa+n *  a[n]  *(a+n) a[n]  *(pa+n) * a[n]  pa[n] * *(a+n)  *(pa+n) * *(a+n)  pa[n] * pa[n]  *(pa+n) * falls pa die Anfangsadresse von a enthält • Strings: Arrays aus Strings (also Arrays vom Typ „char“) werden dadurch geformt. dass er z. „String“). Beispielsweise kann mittels „short *zeigername = arrayname“ ein Zeiger mit der Anfangsadresse initialisiert werden. o Wenn ein Operator oder eine Funktion auf ein char-Array trifft.und Indexausdrücken („a“ bezeichnet das Array. (auch möglich mittels Zeiger: „char *a = „String“. mittels „cout << &array/zeiger“ oder „printf(„%p“. um ein char- Array zu füllen.

der Inhalt von b nach a übertragen werden.B. o Strings können auch verkettet werden mittels der Funktion „strcat“.B.“. Dadurch liest man maximal 63 Zeichen in das Array a ein.B. Leerzeichen) beendet cin (bzw. Beispielsweise definiert „short b [4] [4]“ ein Array aus 4 x 4 = 16 Elementen.b). (Strings lassen sich aber auch sehr einfach mittels „strcpy“ duplizieren. dass bei zweidimensionalen Arrays die Formel: „name_des_arrays [Zeile] [Spalte]“ gilt.und Ausgabe können natürlich auch konventionell durchgeführt werden mittels „scanf(„%s“. das folgende Syntax hat: „strlen(array_adresse)“. i < n. • Die Eingabe geht zeilenweise vor sich. kopiert ab dem 5.“ definiert wurde. adresse_des_quellarrays)“. z. Grundsätzlich werden Arrays von hinten beginnend lesen. adresse_des_quellarrays)“. wobei die unterste Ebene elementare Datentypen enthält. Zeichen in b nach a. die folgende Syntax aufweist: „strcat(adresse_des_zielarrays. Mehrdimensionale Arrays • Mehrdimensionale Arrays (die man sich graphisch als Tabellen oder Tabellen-Quader vorstellen kann) bestehen aus zwei oder mehr ineinander geschachtelten Arrays.h“ am Programmkopf eingeschlossen werden muss.01 . strcpy(a. • Die Syntax folgt dem eindimensionalen Fall: typ_der_arrayelemente name_des_arrays [eintrag1] [eintrag2] … [eintragn]. „strcmp“ hat die Syntax „strcmp(adresse_array1. C++ KOMPENDIUM 34 Rev. o Vorsicht: Nach Angabe eines Zwischenraumzeichens (z. da bei der höchsten Ebene mit der Inidizierung begonnen wird: wenn beispielsweise ein Array mittels „short a[4][3]. 1. adresse_array2)”. das mit der Include-Datei „string. (z. Damit wird das Quellarray wird an das Zielarray angehängt.“ und „cin >> a. o Die Stringlänge kann ermittelt werden mit „strlen“. • Indizierung des Arrays geschieht gemäß der Syntax: „name_des_arrays [ index1 ] … [ indexn ]. scanf) die Eingabe! o Kopieren von char-Arrays: Sind zwei char-Arrays a und b mit n Elementen gegeben. Ein. Das bedeutet. i++) a[i] = b[i]. a). dessen erstes nicht mit dem anderen String identisches Zeichen einen größeren Codewert in der Zeichentabelle (ASCII-Code) des Rechners besetzt. Soll nur ein Teil kopiert werden: strcpy(a. bezeichnet a[0][3] das erste („[0]“) Element des vierten („[3]“) eindimensionalen Teilarrays von a. und eine Kontrollvariable „int i“ definiert. z. kann mittels for ( i = 0.b[4]). a). o Alternativ kann man auch auch explizit „char a[64].“ und „printf(„%s“. o Strings können verglichen werden mit „strcmp“: Derjenige String ist größer. Syntax: „strcpy(adresse_des_zielarrays.B.“ angeben. „abcdef“ größer als „abcDef“ und „abcDefg“).

wie viele Zeichen es pro Element werden! Dies ist eine häufige Fehlerquelle! C++ KOMPENDIUM 35 Rev. „tuesday“. Theoretisch würde hier auch die Angabe „long array[ ][2] = { 1.“ . Zeigerarrays • Zeigerarrays sind Arrays. da der Compiler daraus die nötige Zeilenanzahl automatisch bestimmt. „wednesday“}. spalte < anzahl_spalten. • Vorsicht: Wenn Werte für Zeigerarray direkt von der Tastatur eingelesen werden sollen. weiß der Compiler vorher nicht. for (zeile=0. ist „int *zi[10]" ein Array aus zehn Zeigern auf Datenobjekte des Typs int. Der Zugriff. 1. • Daraus folgt die Schreibweise für Array aus Zeigern: „char *c[3] = { „monday“. andererseits gibt „cout << zi[0].B. • Initialisierung: bei einzelner Angabe der Initialisierungswerte.4}.Zeile einen gemeinsamen Wert zu: for(spalte=0. Diese Syntax ist effektiver als die gewöhnliche zweidimensionale Array-Schreibweise.“ und „zi[0] = &i. • Zuweisungen können ebenfalls wie bei zweidimensionalen Arrays gemacht werden: „c[0][0] = ’M’. spalte < anzahl_spalten.3.“ bzw. zeile++) for(spalte=0. spalte++) cin >> a [zeile][spalte]. Oder man weise beispielsweise allen Elementen der 2.01 . int zeile.“ definiert. zeile < anzahl_zeilen.“ gibt den Wert von i (1) aus. spalte.4}“ genügen. z.“ die Adresse von i aus.“ wird wiederum zeilenweise eingelesen.B. über „cout << c[0]“ erfolgt. Wird nun „int i = 1.B durch „long array[2][2] = {1. deren Elemente Zeiger auf Datenobjekte sind. den Indexausdruck als Zeigerausdruck zu formulieren: „a[i1][i2][i3]“ entspricht „*(*(*a+i1)+i2)+i3)“. der z. „cout << &zi[0].3. • Es ist möglich. so verweist zi[0] danach auf i.“ macht aus „monday“ „Monday“. • String-Arrays werden wie im eindimensionalen Fall behandelt. z.2. ändert sich aber nicht.2. spalte++) cin >> a [1][spalte] = wert. • Ein „cout << *zi[0].

• Bei der Allokation von dynamischen Arrays (deren Element-Anzahl nicht von Anfang an feststeht) können keine Initialisierungswerte angebeben werden.“ nicht möglich. • Arrays zu allokieren erreicht man mittels der Syntax zeiger = new datentyp [ elementezahl ]. Beispiel: int *x. die durch die übliche Syntax: zeiger = new datentyp [elementzahl1] [elementzahl2] …. x = new int.B. wenn z. deren Syntax sich folgendermaßen gestaltet: zeiger = new datentyp [ (initialisierungs_ausdruck) ]. 1. kann man die Funktion „new“ benutzen.5). • Bei mehrdimensionalen dynamischen Arrays. im Speicher allokiert und zugewiesen. C++ KOMPENDIUM 36 Rev.“. Beispielsweise kann durch eine zusätzliche Anweisung mittels einer Variablen die Anzahl determiniert werden.2. 7. Ebenfalls kann während der Programmlaufzeit Speicherplatz wieder frei gegeben werden. Ein „cout << *y“ würde in diesem Beispiel „3“ ausgeben.B. und das Array wird mit der Adresse des ersten Elements initialisiert.4.01 . z. o Damit muss die Anzahl der Elemente des Arrays nicht notwendigerweise mehr eine Konstante sein. die Größe eines Arrays nicht von vornherein klar ist. ist „int *array = new int [5] (1. durch „short *y = new short(3). z. wenn er nicht mehr benötigt wird. mit Hilfe der Funktionen „delete“ oder „free“. durch „int *array = new int[5].B. Hier wird ein Zeiger x definiert.B. Mit Hilfe der Funktionen „malloc“ und „new“ kann der Speicherplatz während des Ablaufs des Programms verwaltet (allokiert) werden.“ Dadurch wird Speicherplatz für 5 int-Objekte allokiert.3. Der Zeigertyp und der allokierte Datentyp müssen von gleicher Art sein • Initialisierung: Weise der Allokationsanweisung einen Initialisierungswert zu: z. sondern erst zur Laufzeit eines Programms bestimmt wird. Speicherverwaltung • Man spricht von aktiver oder dynamischer Speicherverwaltung. Speicherverwaltung mit „new“ • Um einzelnen Objekten Speicher zuzuweisen.

01 . • Die Allokation dynamischer Arrays mit doppeltem Zeiger folgt dem Muster: char **namen = new char*[anzahl_der_einträge].“ Beispielsweise würde nach der Definition int i = 1.“ • „delete“ kann nicht zur Löschung eines Zeigers auf ein konstantes Datenobjekt verwendet werden. ein Zeiger auf einen Zeiger benötigt. C++ KOMPENDIUM 37 Rev. z1[1] auf 1 bzw. zur Fehlerkontrolle eine Zeile folgenden Musters einzuschließen: if ( array == 0) cout << „Fehler bei der Allokation!“. wird wie für jedes andere dynamische Array auch. • Der Zugriff auf mehrdimensionale dynamische Arrays ist identisch mit dem der gewöhnlichen mehrdimensionalen Arrays. *zi = &i.B. Jetzt verweisen z1[0] bzw. und i äquivalent. ein Zeiger auf einen Zeiger folgendermaßen aussehen: int **zzi = &zi. 2. • Um ganze Arrays löschen. Damit sind jetzt **zzi. Es empfiehlt sich. wird der Nullzeiger vom Programm zurückgegeben. *zi. • Sollte ein Fehler bei der Allokation auftreten (wenn z. nicht genügend Speicher für das Array frei ist). der mit „new“ allokiert wurde.2}“. • Zeiger auf Zeiger bei Arrays: Seien beispielsweise „char 1[] = „abc““ und „char 2[] = „def““ definiert. Der Datentyp der Zeigerrückgabe ist der der obersten Ebene des Arrays. sowie „char *z1[2] = {1. Speicherfreigabe mit “delete” • Man kann Speicherplatz.B. mit „delete“ wieder frei geben (sog. z.“ Zeiger auf Zeiger • Beispielsweise für dynamisches Array aus Zeigern. darf nur die erste Arraydimension variabel sein! Alle anderen hingegegen müssen konstant bleiben. Deallokation). bediene man sich der Syntax „delete [ ] zeiger. mit einer Ausnahme: der verwendete Zeiger ist jetzt statt des Arraynamens eine reguläre Zeigervariable. eingefügt werden. die auf Zeichenketten verweisen. Die Syntax ist denkbar einfach: „delete zeiger. 1. array [0] [0] = 2. • Die Syntax für einen solchen Zeiger lautet: datentyp_des_verweisobjekts **name_des_zeigers.

Dabei ist „anzahl_bytes“ vom Typ „unsigned int“. blockgröße). • free: Mit „free“ wird eine Freigabe des von anderen Funktionen allokierten Speicherplatzes erreicht. „realloc“ folgt der Syntax: zeiger = (typ_des_zeigers) realloc (zeiger. i = (int*) calloc(10. und schließlich erfolgt eine Initialisierung mit der Adresse des Blocks.01 . „realloc“ (das eine Reallokation bewirkt) und „free“ (das eine Freigabe des Speicherplatzes nach sich zieht). Dies geschieht gemäß der Syntax: „free(zeiger). 1. • calloc: bei dieser Funktion werden alle Elemente mit dem Wert 0 initialisiert. Hier geschieht zunächst eine Zeigerdefinition. dann eine explizite Konvertierung in die Form „int“. sizeof(int)). Wenn als Zeiger der Nullzeiger („NULL“) angegeben wird.h“ in den Programmkopf eingeschlossen werden. „calloc“ besitzt folgende Syntax: zeiger = (typ_des_zeigers) calloc (elementezahl. • realloc wird zur Änderung des Speicherplatzes bzw. verhält sich realloc genau wie malloc. Diese Funktionen müssen mit „stdlib. und die Adresse des allokierten Blocks wird in der Form eines generischen Zeigers „void*“ gespeichert. elementgröße). der Speichergröße verwendet. o Beispiel: int *i = (int*) malloc(10*sizeof(int)). Dynamische Speicherverwaltung • C++ hält einige Funktionen zur dynamischen Speicherverwaltung bereit. wodurch eine explizite Konvertierung in den Typ des Zeigers auf der linken Seite notwendig wird. • Malloc/calloc: haben folgende Syntax: zeiger = (typ_des_zeigers) malloc (anzahl_bytes). o Beispiel: int *i.“ C++ KOMPENDIUM 38 Rev. dann wird eine Speicherallokation für 10 int-Objekte durchgeführt. wie etwa „malloc“ und „calloc“ (die zur Allokation dienen). .

cpp“. • Wenn die Anweisungen/Definition der Funktion in einer anderen Datei stehen. 1. keinen Rückgabewert (void). Diese Einteilung bestimmt dann auch ihren Gültigkeitsbereich. aus einer Anzahl von Parametern. • Beispiel: void funktion (int a. Eine Deklaration wird erforderlich. beim MS-Compiler durch: „cl programm. (Wenn die Header-Datei im Default-Ordner für include-Dateien gespeichert wird. • Funktionen können lokal und global deklariert werden.01 . typ2. z. und eine Anweisungen (a+b).h“. o Block: Die Gültigkeit endet nach Ende des Blocks – sie ist lokal. Gültigkeitsbereiche • Es existieren verschiedene Gültigkeitsbereiche („scopes“) für Datenobjekte: Block. ist eine Pfadangabe nicht nötig). Sie haben allgemein folgende Syntax: typ_des_rückgabewerts name_der_funktion ([typ1. aus Anweisungen (was mit den Parametern geschehen soll). zwei Parameter (int a. name1. name2. int b). C++ KOMPENDIUM 39 Rev. und aus einem Rückgabewert. } Diese Funktion hat den Namen „funktion“. {a+b. Deklaration von Funktionen (Prototypen) • Die Deklaration einer Funktion hat eine identische Syntax wie ihre Definiton. nur sind jetzt die Typangaben optional. und Klasse. binde man den Code der Funktion in ein neues Programm durch eine explizite Angabe beim Kompilieren ein. und die Deklaration ist mit einem Semikolon abzuschließen. 8. b). • Deklaration mittels Include-Dateien: Schreibe Header-Datei (*. und schließe diese dann mittels #include „Pfad:\headerdatei. wenn sich der Aufruf der Funktion vor ihrer Definition befindet. Funktionen Definition und Aufruf • Funktionen bestehen aus ihrem Namen.cpp einzubindende_funktion. Datei. …]) { anweisung(en) } Angaben in eckigen Klammern sind hier optional.B.h) für Funktionsdeklarationen.

was einen schnelleren Zugriff ermöglicht.h. 1. damit auch im zweiten Programm der Zugriff auf die Variable möglich wird. Die Deklaration einer globalen Variable a muss vor einem Zugriff auf a erfolgen – d. • Funktionen mit Rückgabewert haben die Syntax „return ausdruck.“ den globalen Wert einer Variable aus.01 .B. „extern int a. o Klasse: Die Funktion ist innerhalb der Klasse gültig. außer dass die Variable nicht im RAM. • Für dateiübergreifend gültige Konstanten muss „extern“ bereits bei der Definition hinzugefügt werden. z. • static: Gültigkeitsbereich ist der Block. danach wird die Variable gelöscht. • Globale Variablen sind implizit „static“. Mit „static“ ist die Variablendefinition gültig für die Dauer des Programms.B. o Datei: Gültigkeit auch außerhalb aller Funktionen und Blöcke. C++ KOMPENDIUM 40 Rev. Rückgabewerte: die “return”-Anweisung • Mit „return“ erfolgt eine explizite Beendigung der gegenwärtigen Anweisung und eine Rückkehr zu aufrufender Funktion. • auto ist die default-Einstellung.“. ein Programm „int rueckgabe( )“ definiert wurde. definiert. mit „auto“ oder „register“ nur für den ihr zugewiesenen Programmteil. Z. • Dateiübergreifende Gültigkeitsbereiche: werden mittels der Syntax extern datentyp_der_variablen name_der_variablen. gibt „::globaler_Name. • Eine Explizite Beschränkung des Gültigkeitsbereiches einer Variablen auf ein Programm ist mittels „static“ bei der Definition der Variablen möglich (z. die Lebensdauer der Variable ist global.“ einen Rückgabewert zurück. „static int a = 1. • register: ist identisch mit auto. Die Variablendefinition ist gültig für die Ausführung des Programms.“ Wenn z.B. sondern im Prozessorregister gespeichert wird. zuerst muss eine Definition im Programm erfolgen. Beachte: die Typen müssen übereinstimmen. oder mit Hilfe des Bereichszugriffsoperators „::“.“ oder „return (ausdruck).B. • Zugriff auf überdeckte Variablen (gleichnamige Variablen mit verschiedenen Gültigkeitsbereichen innerhalb eines Programms) ist beispielsweise mittels expliziter Zeigerdefinition auf eine der Variablen möglich.“) Lebensdauer von Variablen • Die Lebensdauer von Variablen kann mittels dreier Optionen bestimmt werden. gibt „return (int1). dann eine extern-Deklaration im anderen Programm angeführt werden. hier muss beispielsweise „int1“ vom Typ „int“ sein. die Funktion ist global gültig.

die innerhalb einer Funktion für eine Rechenanweisung verwendet werden. • Paramterübergabe per Adresse („pass by reference”) unterteilt sich wiederum in zwei Optionen. immer per Referenz übergeben. also Adressangaben. • Wenn Parameter eingeschlossen werden.01 . „void funktion1(short *arr)“ (Formalparamter in Zeigersyntax) oder „void funktion1(short arr[ ])“ oder „void funktion1(short arr[10])“.“ ein Zeiger definiert und mit der Adresse von s initialisiert werden. • Referenzen. werden sie dadurch definiert und haben Gültigkeit bis zum Funktionsende. oder enthalten das Schlüsselwort „void“. o Arraygröße: Anzahl der Ausgabelemente kann mit zusätzlichen Parameter angegeben werden. 1. Wenn eine Funktion keine Parameter hat. Damit betreffen eventuelle Modifikationen nicht eine Kopie des Arrays. und damit auch der Rückgabewert im späteren Verlauf vom Programm modifiziert werden. bei „funktion1(wert1.B. und die Parameterübergabe per Adresse. Dann ist anstatt „funktion1(wert1. wert2. • Arrays als Paramter: Arrays werden. Element ausgegeben werden: „show (&arr[2]. möglich. Nur der Arraynamen ist als Paramter anzugeben. Allgemein wird also mittels einer Defintion typ array_name [ebene_1] … [ebene_n] C++ KOMPENDIUM 41 Rev. long &z)“ die Werte „wert3“ und „wert4“ per Wert und s per Referenz an funktion1(wert1.B. die Übergabe mit einem Zeiger. kann mit „*pz = &z.B. wert2. sondern das Original. bleiben die runden Klammern bei Definition bzw. wert2 und die Adresse von z an den Aufruf der Funktion „funktion1“ übergeben. obwohl diese Methode im Grunde eine Übergabe per Wert entspräche. o Zeiger-Übergabe: z. 2). die Parameterübergabe per Wert. wie die Parameter dem Programm übergeben werden. int n)“ eine Funktion zur Anzeige der Arrayelemente definiert. weil eventuelle Modifikationen an z am Originalwert von z durchgeführt werden. Beispiel: Sei mit „void show(short *arr. Parameter • Parameter sind die Bestandteile. pz). der Deklaration leer. long wert4. &z). sondern mittels der Referenz ein direktes Äquivalent für sie. • Die Parameterübergabe per Wert („pass by value”) ist die default-Einstellung in C++.“. wert2. Z.“ auch funktion1(wert1. Der Rückgabewert ist dann eine Referenz auf die Variable und keine Kopie ihres Wertes. Im Allgemeinen ist diese Methode bequemer als die Übergabe per Zeiger. und sollen das 3. und 4. und die Übergabe mit einer Referenz. Deshalb kann ihr Wert. können ebenfalls als Rückgabewerte verwendet werden. damit die Adresse gespeichert werden konnte und der Zugriff mittels des Adressoperators „&“ möglich wird. wert2. o Mehrdimensionale Arrays: Adressangabe bezieht sich – nicht wie sonst! – auf die oberste Arrayebene. Äquivalent sind z. Dabei gibt es zwei Möglichkeiten. Hat arr beispielsweise 4 Elemente. mit n als Anzahl der Ausgabelemente. o Referenzen-Übergabe: Beispielsweise übergibt „void funktion1(long wert3. &z). z). und nicht nur an einer Kopie.“ werden die Werte von wert1. wenn sie Parameter einer Funktion sind. Allerdings muss bei der Definition der Funktion der ein Zeiger definiert worden sein.

Wenn die Schleife abbricht. Kommandozeilen-Parameter sind aktuell. • Default-Paramter: Der Wert eines Aktualparamters kann bereits bei der Funktionsdefintion angegeben werden – z. • Funktion kann sich auch selbst aufrufen (z. „funktion(5.000)“ . Funktionsnamen überladen • Wenn eine Operation in gleicher Art und Weise mit einer unterschiedlichen Anzahl von Objekten oder verschiedenen Typen von Objekten ausgeführt werden soll.000)“ aufgerufen wird.01 . und einem Aufruf funktion1(array_name) ein Zeiger der Form „typ *[ebene_2] … [ebene_n]“ notwendig. nicht erst bei der Laufzeit des Programms. „double funktion(double x = 1. Anzahl und Position von default-Angaben sind von rechts beginnend und nach links aufstockend anzugeben. z. die das Programm verwenden soll. gehören nicht zur Funktion selbst. Die Klammerung ist hier wegen der hohen Priorität von [] notwendig.B. können sie nicht mit demselben Namen bezeichnet werden. z. „argv[0]“. und die schon beim Aufruf von „main“ eingegeben werden können. kann ein Funktionsname mehrere Funktionen bezeichnen. • Konstante Parameter: Bei konstanten Parametern ist die Übergabe per Wert unproblematisch – allerdings können bei Übergabe per Referenz Konvertierungsprobleme auftreten. • Beachte: Die Rückgabewerte und die Formalparameter. z. Der erste Zeiger dieses Zeigerarrays. Man bestimme deshalb einen zugehörigen Formalparameter mit „const“.Wenn jedoch die Funktion mit anderem Wert.B. „int funktion(int *a. int b)“ und „double funktion(double *a. void funktion1(const char x[]).B. Dabei bezeichnet „argc“ die Anzahl der eingegebenen Parameter und „char *argv[]“ das Zeiger-Array für diese. weil sie für den Compiler identisch sind. Die Funktion “main” • Die Hauptroutine „main“ darf nicht überladen oder aus dem Programm heraus aufgerufen werden. mit einer if-Schleife. Beispiel: bei „int arr[3][4]“ und „void zero(int (*arr)[4])“ ist „arr“ ein Zeiger auf 4-elementige int- Arrays. C++ KOMPENDIUM 42 Rev.B. endet die Rekursion und das Programm kehrt zum ersten nicht-rekursiven Aufruf zurück). 1. • Kommandozeilen-Parameter sind Werte. wenn sich also zwei Funktionen nur in Bezug auf diese unterscheiden. int b)“. die zugehörigen Formalparameter für main sind mit „int argc“ und „char *argv[]“ konventionell vereinbart. verweist dabei auf den Programmnamen. Der Compiler legt implizit Zeichenarrays für Kommandozeilen-Parameter an. die in einer Funktion verwendet werden. wird der default-Wert ignoriert.B.

der letzte argv[argc] auf den Nullzeiger. durch „int (*f)(double d) = g. Deshalb müssen Inline-Funktionen vor ihrem Aufruf definiert werden.B. Bei einer Funktion f stellen „f“ und „&f“ beide einen konstanten Zeiger auf den Anfang des Funktionscodes dar.10 Zeiger auf Funktionen • Die Funktionsadresse einer Funktion beinhaltet die Adresse auf den ausführenden Code- Teil. 1.01 . C++ KOMPENDIUM 43 Rev. der zweite argv[1] auf den ersten „echten“ Kommandozeilenparamter.“). eine Deklaration an gewünschter Stelle reicht nicht aus! Zur Vermeidung von Fehlern kann man eine Inline-Funktion auch in eine eigene Header-Datei schreiben und mittels einer #include-Anweisung einschließen. die Anweisungen der Funktion. z. kann mittels g(wert) oder (*f)(wert) oder f(wert) die Funktion aufgerufen werden. 8.h. Sie werden mittels folgender Syntax angegeben: inline typ_rückgabewert name_funktion(paramterliste) { [anweisungen] }. • Inline-Funktionen können wie Makros expandiert werden. stellt „int (*f)(double d)“ einen Zeiger f auf Funktionen mit einem double-Parameter und Rückgabewert int dar (hier sind die Klammern wegen der Setzung der Priorität notwendig).B. d. d. Inline-Funktionen • Inline-Funktionen kombinieren die Schnelligkeitsvorteile von Makros mit einer geringeren Fehlergefahr im Quelltext.h. • Wenn die Funktion dann noch intialisiert wird (z. der Compiler ersetzt einen Funktionsaufruf durch den entsprechenden Quelltext.

• Eine Klasse darf sich nicht selbst als Element beinhalten (aber sie darf einen Zeiger auf sich selbst beinhalten) • Elementfunktionen: Für Funktionen.01 .}. • Typendefinitionen sind innerhalb von Klassen möglich: z. Geht Klasse 2 aus Klasse 1 hervor. wird 1 als Basisklasse von 2 bezeichnet (siehe Punkt „Vererbung“) • Spezifikation von Datenelementen. 9. C++ KOMPENDIUM 44 Rev. 1.“ definiert wurde. oder „union“). es ist also keine explizite Parameterübergabe notwendig. die innerhalb einer Klasse verwendet werden sollen. ersteKlasse x. double 2. wird ihren Elementen noch kein Speicherplatz zugewiesen – sie können deshalb noch nicht initialisiert werden. • Beispiel: „class ersteKlasse {} x. o Außerhalb einer Klasse definierte Funktionen sind nicht automatisch vom Typ „inline“. } Man spricht hier von einem „qualifiziertem Namen“ der Funktion. und daraufhin (optional) die Spezifiktion der Basisklasse. „struct“.“ Nun ist „string_array“ ein Synonym für „char [10]“.“) • Anonyme Klassen: „class { … } a. ist entweder eine Definition der Funktion innerhalb der Klasse oder eine Deklaration innerhalb und die entsprechende Definition außerhalb notwendig. Klassen Eine Klasse ist eine informatische Modellbildung eines gesamten Objektes mit allen seinen Parametern.B. also beispielsweise void KlasseA::funktion(double x) { anweisungen. o Elementfunktionen haben direkten Zugriff auf alle Klassenelemente. die die Klasse verwalten soll: Wenn z. dann folgt der Name der Klasse.“ definiert eine Klasse „ersteKlasse“ und ein Objekt x dieser Klasse (alternativ: „class ersteKlasse {}. o Innerhalb einer Klasse definierte Funktionen sind automatisch vom Typ „inline“. o Außerhalb einer Klasse definierte (und in der Klasse deklarierte) Funktionen müssen eine Referenz auf ihre Verwendung in der Klasse beinhalten. eine Klasse mittels „class A { double 1. Eine Klasse ist ein „Bauplan“ für Objekte. aber mit Objekt „a“. Definition von Klassen • Eine Klasse wird gemäß der folgenden Syntax definiert: Zuerst wird ein Schlüsselwort angeführt (entweder „class“. mittels der Syntax klassen_name::funktions_name . durch „typedef char string_array [10].B.” definiert eine Klasse ohne Namen. • Basisklassen: Es ist möglich. dass eine Klasse das Modell einer anderen ist.

ein „public-interface“ zu setzten. o public: Mittels „public“ wird ein globaler Zugriff möglich. Lokale Klassen haben keinen Zugriff auf Variablen der Elementfunktion oder der übergeordneten Klasse. • Gültigkeit von Definitionen von Objekten sind generell auf die jeweilige Klasse beschränkt. „public“ oder „protected“.B. der vor die Definition des Objekts gesetzt wird. z. und zwar mittels des Zugriffsspezifizierer „public“. z.B. c[5]. die als „friends“ der Klasse deklariert werden. wird automatisch „private“ gesetzt. • Lokale Klassen sind innerhalb einer Klasse oder einer Elementfunktion definierte Klassen. ist es möglich. mittels der Schlüsselworte „private“.datenelement_name“ bzw. nach folgendem Muster: „objektname. • Klassendefinitionen innerhalb von Klassen sind problemlos möglich.01 . der für den Zugriff verwendet wird. eine oder mehrere Elementfunktion(en). definiert „name_der_klasse a. Der Gültigkeitsbereich ihrer Definitionen ist wie bei Variablen auf diesen Block beschränkt. Allgemein kann man mit einem Zugriffsspezifizierer die Regeln des Zugriffs auf Objekte der Klasse festlegen. • Die Deklaration von Klassen folgt der Syntax: „class name_der_klasse. Elementfunktionen von lokalen Klassen müssen innerhalb ihrer Klasse definiert werden (wodurch sie implizit als „inline“-Funktionen festgelegt werden). o private: Der Zugriff auf private-Elemente ist nur den Elementfunktionen der jeweiligen Klasse erlaubt oder den Funktionen. Objekte einer Klasse • Die Definition neuer Objekte einer Klasse geschieht analog zur Definition von Variablen.aufruf_elementfunktion“.“ zwei Objekte a und b des Typs „name_der_klasse“ und ein Array aus fünf name_der_klasse-Objekten. jedoch auf deren statische Variablen. d. o protected: Der Zugriff auf protected-Elemente ist für Elementfunktionen (und „friend“-Funktionen) sowie Elementfunktionen abgeleiteter Klassen (und deren „friend“-Funktionen) möglich. • Zugriff auf Klassenelemente: Der Zugriff ist nur innerhalb ihres Gültigkeitsbereiches ohne weiteres möglich. Wenn keine Spezifizierungs-Angabe erfolgt. einen ganzen public-Abschnitt zu definieren.h. • Bei jeder Neudefinition eines Objektes einer Klasse wird – im Gegensatz zur Definition innerhalb der Klasse – Speicherplatz für das Objekt allokiert. und dem Bereichszugriffoperator „::“. jedoch können keine Objekte der Klasse erzeugt werden (was eine vorhergehende Definition erfordern würde). • Um Zugriff auf private-Klassen zu erhalten. Allerdings bleibt die Möglichkeit des Zugriffs von außerhalb unberührt vom C++ KOMPENDIUM 45 Rev. b.“ Damit können bereits vor der Definition Zeiger und Referenzen auf die Klasse festgelegt werden. • Zugriff von außerhalb ist mittels des Punktoperators möglich. 1. „objektname. Die Übergabe erfolgt per Wert. • Zuweisungen sind mittels einer einfachen Gleichsetzung „objekt1=objekt2“ möglich. Ein Zugriff auf ein Objekt von außerhalb der Klasse ist dennoch möglich. Objekte müssen von gleichem Klassentyp sein (außer: bei elementaren Datentypen erfolgt eine implizite Konvertierung).

„Klasse1 class1. Zugriffstatus. Alternativ kann auch die Definition und die Initialisierung zusammengefasst werden. in der üblichen Syntax: „zeiger_auf_objekt ->* elementezeiger“. • Zeiger auf Elementfunktionen haben die Syntax: typ_rückgabewert (name_klasse::*name_zeiger) (paramterliste).element_1 = 1. mittels der Syntax: „zeiger->element“. „z->element_1 = 1.: double Klasse1 :: *z = &Klasse1::element_1. z. Eine Alternative Schreibweise ist mit dem Pfeil-Operator „->“ möglich. sind die Punktoperatoren hintereinander zu schalten. • Wenn ein Element einer Klasse 1 wiederum Objekt einer anderen Klasse 2 ist.“ mittels „class1.23. Beispielsweise definiert „double Klasse1:: *z. werden gewöhnlich in Klasse nur deklariert und in einer eigenen cpp-Datei definiert (in dieser ist dann die Klassendefinitions-Datei einzuschließen). 1. lässt z auf element_1 der Klasse „Klasse1“ zeigen. z.“ • Zeiger auf Datenelemente haben die Syntax: typ_des_elements name_der_klasse:: *name_des_zeigers. empfiehlt sich die Definition der Klassen mittels einer eigenen Include-Datei.“ auf z zugreifen.: z = &Klasse1::element_1. der nur auf Elemente des Typs double der Klasse „Klasse1“ zeigen kann. z. Die Funktionen einer Klasse. • Zugriff auf Objektarrays ist mittels des Punktoperators innerhalb folgender Syntax möglich: objektarray_name[index]. Außerdem ist der Zugriff auf „private“-Elemente der Klasse nicht möglich. Eine Klammerung von *z ist hier wegen den Prioritäten notwendig. Zum Beispiel ist „void(Klasse1::*z)(double) z“ ein Zeiger auf Klasse1-Funktion ohne Rückgabewert und einem Parameter (Klammerung ist auch hier wieder wegen den Prioritäten notwendig).01 .“ einen Zeiger. Eine Initialisierung erfolgt beispielsweise mittels C++ KOMPENDIUM 46 Rev. Alternativ ist auch hier wieder der Pfeiloperator möglich. ein Wert zugewiesen werden.2_element • Grundsätzlich: Wenn viele Klassen innerhalb eines Programms verwendet werden.B. definiert einen Zeiger Klasse1. die nicht vom Typ „inline“ sind.234.B. Nun kann z. kann man nach einer Definition eines Objektes der Klasse „Klasse1“. z. Zuweisungsoperationen ist wiederum der Bereichszugriffoperator „::" notwendig. und initialisiert z mit der Adresse des Objekts. der für das betreffende Element in der Klassendefinition festgelegt wurde.234.B. Beispiel: 1_objekt.bzw. z.*z = 1.B. • Mittels „objekt.datenelement_bzw_Elementfunktion_name. • Bei Initialisierungs.*elementzeiger“ lässt sich dann auf das gewählte Objekt zugreifen.2_objekt. dem Element „element_1“ dieses Objekts mittels (*z). • Pfeiloperator: beispielsweise allokiert „Klasse1 *z = new Klasse1“ ein Klasse1-Objekt.B.B.

o Das Gegenteil ist eine „tiefe“ Kopie.01 .*z)(1. legt Compiler implizit einen Standardkonstruktor an. o Bei Arrays: Enthält die Initialisierungliste für ein Array weniger Elemente. was äquivalent zu „Klasse1. und die Adresse des Datenduplikats in den Zielzeiger übertragen wird. • Konstruktoren sind Elementfunktionen. • this-Zeiger: der „this-Zeiger“ ist ein Zeiger für die Objekte. noch Basisklassen. werden Nullen ergänzt. die Klassenobjekte konstruieren. oder Funktionsaufrufe mittels Punktoperator verkettet werden sollen. Initialisierung und Konstrunktion von Objekten • Initialisierungslisten: Wenn eine Klasse nur public-Elemente. o Ein Aufruf der Elementfunktion erfolgt mittels (objekt. als bei der Definition verlangt wurde.23).“ ist. o Eine explizite Verwendung des this-Zeigers wird nötig. Dies initialisiert z mit der Adresse der Funktion „funktion1“. und innerhalb deklariert werden. die nur die Zeiger. wenn z. Bestimmte Elemente können vom Rumpf in den Kopf eines Konstruktors verlagert werden (s.23). mit denen eine Elementfunktion operiert. Dies wird mit der Hilfe von Konstruktoren erreicht. Konstruktoren besitzen keine Rückgabewerte (deshalb auch keine Typspezifizierung). „flache“ Kopien.B. o Der Name des Konstruktors ist stets mit dem der Klasse identisch. unten).funktion1(1. void(Klasse1::*z)(double) = Klasse1::funktion1. o Mit bereits initialisierten Objekten können andere Objekte derselben Klasse per Zuweisung initialisiert werden. Zum Beispiel ist C++ KOMPENDIUM 47 Rev. 1. Jede Elementfunktion einer Klasse enthält diesen Zeiger implizit als verborgenen Formalparameter. und den nötigen Speicherplatz allokieren.*elementzeiger) (parameterliste) oder (zeiger_auf_objekt ->* elementzeiger) (parameterliste) Beispiel: „(Klasse1. sie initialisieren. bei der Datenbereich dupliziert wird. o Wenn Konstruktor nicht explizit vom Programmierer definiert wird. dann können mit in „{ }“ eingeschlossenen Werten die Objekte dieser Klasse initialisiert werden. o Ein Konstruktor kann wie bei anderen Elementfunktionen außerhalb der Klasse definiert. aber nicht die Werte kopieren. Achtung: dies sind sog.“ ruft die Funktion „funktion1“ über Zeiger den Zeiger z auf. Parameternamen Elementnamen überdecken sollten. noch virtuelle Funktionen besitzt. aber weder Konstruktoren.

Referenzen. Hier wird z. o Konvertierungskonstruktoren wandeln ein Objekt in eine Klasse um. o Kopierkonstruktoren: beispielsweise kann „Klasse1 a. oder Klassenobjekte sind. bevor der Konstruktor der Klasse ausgeführt wird. int d).4).01 .. int a. o Alternativ kann der Konstruktor auch explizit aufgerufen werden. o Der Konstruktor benötigt beim Aufruf die exakte Anzahl der Parameter. Ebenfalls besitzt der Konstruktor wie eine normale Elementfunktion einen this-Zeiger.“ eine Zuweisung „Klasse1 b = a. 1. o Wie üblich werden aktuelle Paramter von links nach rechts in die formalen Parameter übertragen. wenn Datenelemente Konstanten. wenn die Klasse einen benutzerdefinierten Konstruktor besitzt. ] (Eckige Klammern signalisieren hier optionale Elemente). o Elementobjekte: Zur Initialisierung eines Elementobjekts wird ein Konstruktor der Klasse verwendet. element_2 (init_ausdr). Der erste Formalparameter ist von einem anderen Typ als die dem Konvertierungskonstruktor eigene Klasse (sonst wäre er ein Kopierkonstruktor). o Der Standardkonstruktor initialisiert nur statische und globale Objekte implizit mit Null.B.. die das C++ KOMPENDIUM 48 Rev. in dem sie aufgerufen und verwendet werden können. Dieser Konstruktor wird ausgeführt.“ erfolgen. Kopierkonstruktoren sind mit einem einzelnen Parameter aufrufbar (wobei alle eventuellen anderen Parameter default-Werte besitzen müssen). }. und haben dementsprechend ihren Bereich. eine Kopie über den Standardkonstruktor gemacht.B. o Beispielsweise definiert „Klasse1 x(2. hingegen abc::abc(int c. nur ein Parameter beim Konstruktoraufruf angegeben werden. eine Konstruktordeklaration.“ ein Klasse1-Objekt x und übergibt die Parameter 2 und 4 an den Konstruktor. int d) { a = c. Lokale (nicht-statische) Objekte erhalten keinen definierten Anfangswert durch den Standardkonstruktor. der sie in die Datenelemente von x überträgt. . public: abc(int c. public. Dann kann z. Dies geschieht mittels Aufruf des Standardkonstruktors ohne Parameterangabe. o Konstruktoren sind wie alle anderen Klassenelemente den Zugriffsspezifizierern (private. Sie werden mit Hilfe folgender Syntax angegeben: element_1 (init_ausdruck) [ . die den Typ des Elementobjekts bildet. gemäß der Syntax: „name_konstruktor (liste_aktuelle_paramter)“. o Konstruktornamen sind überladbar. class abc . außer wenn die Parameter bei der Definition mit (beliebigen) default-Werten initialisiert wurden. o Initialisierungslisten für Konstruktoren können als Alternative zu Initialisierung im Rumpf verwendet werden. eine Konstruktordefinition. o Der Standardkonstruktor wird nicht erzeugt.. Sie sind notwendig. b = d. int b.. protected) unterworfen.

die von mehreren Klassenobjekten benutzt werden können (aber keinem in eigener Ausführung bereit stehen. 1. Dies geschieht. Die fehlenden Elemente b[2] und b[3] werden hier mittels des Standardkonstruktors (der definiert sein muss) mit 0 initialisiert. sondern zur C++ KOMPENDIUM 49 Rev. o Zu beachten ist. Konstante/statische Objekte • Klassen können auch als konstante Objekte definiert werden. wenn Lebensdauer eines Objekts der Klasse abgelaufen ist (lokale auto-Objekte. • Statische Klassenelemente sind solche. Falls der Konstruktor Parameter benötigt. ist die Qualifizierung mit „name_klasse::“ nicht notwendig. static-Objekte. auf new-Objekte mittels delete). „Klasse1 (2. z. sowie alle üblichen Klassenelemente). Ist ein Konstuktor mit genau einem Parameter definiert. o Eine Klasse kann über nur einen Destruktor verfügen. o Die Lebensdauer von static-Elementen beginnt bei der Definition und hält bis zum Programmende vor. o Objektarrays: Für die Konstruktion und Initialisierung eines Arrays aus Objekten einer Klasse ist folgendes zu beachten: Ist ein Standardkonstruktor definiert. die das Elementobjekt enthält. „const Klasse1 a(1.30)“ (expliziter Aufruf eines int-int-Konstruktors) }.B. Ist der Konstruktor mit mehreren Parametern definiert. außerdem können keine Elementfunktionen aufgerufen werden.01 . dass konstante Objekte initialisiert werden müssen. Falls die Konstruktordefinition außerhalb erfolgt ist. und nicht neu zugewiesen werden können. um Speicherplatz wieder frei zu geben.“. Ein static-Element gehört nicht zu einem Objekt. o Für dynamische Arrays sind keine Initialisierungslisten erlaubt. o Destruktor hat keinen Parameter (außer dem this-Zeiger) – der Name des Dekonstruktors kann deshalb nicht überladen werden. o Beispiel: „Klasse1 b[4] = { „00:30“ }“ (impliziter Aufruf eines char- Konstruktors). • Konstante Elementfunktionen greifen nicht schreibend auf ihre Datenelemente zu. ist expliziter Aufruf des betr. Das Schlüsselwort für solche Objekte ist „static“. Elementobjekt enthält. o Destruktoren haben die Syntax: name_klasse::~name_klasse ( ) { [Anweisungen] } Eckige Klammern signalisieren hier optionale Elemente. werden diese in der Initialisierungsliste des Konstruktors der Klasse angegeben. kann die Initialisierungsliste entfallen. • Destruktoren werden zum Löschen von Konstruktoren verwendet. Wenn sie innerhalb steht. entsprechende Fehlermeldungen treten bei Zuweisungs. kann für jedes zu initialisierende Objekt des Arrays der Parameter in der Liste angegeben werden. Konstruktors in der Initialisierungsliste für jedes zu initialisierende Objekt notwendig. o Destruktoraufrufe sind fast immer implizit.oder Veränderungsversuchen auf.0).

vor der Definition der Klasse zu stehen hat. Friend-Funktionen und friend-Klassen • Wenn beispielsweise der Zugriff einer Funktion auf private-Elemente einer Klasse von außerhalb gewährleistet sein soll.“ (Definition und implizite Initialisierung mit Null). in der die Elementfunktion als friend deklariert wird.“ Hier ist C++ KOMPENDIUM 50 Rev. (Deklaration). o Statische Elemente sind nur in globalen Klassen erlaubt. muss das Schlüsselwort „mutable“ vor der Definition hinzugefügt werden: Beispiel: „mutable int xb. ist folgende Syntax zu verwenden: „friend class name_klasse. und werden außerhalb ohne „static“ mittels des Bereichszugriffoperators „::“ und qualifiziertem Namen angegeben. z. Wenn aber trotzdem ein Element veränderbar sein soll. o Sollen alle Elementfunktionen einer Klasse zu friend-Funktionen einer anderen werden. oder „protected“ möglich. „public“. o Statische Elementfunktionen besitzen keinen this-Zeiger – und damit keinen direkten Zugriff auf nichtstatische Elemente der Klasse. o Alternativ kann man natürlich auch über einen vorher definierten Zeiger auf das Klassenelement zugreifen. Grundsätzlich gilt die Regel. o Der Zugriff gestaltet sich genauso wie bei gewöhnlichen Datenelementen. und der Konstruktor der zweiten soll auf Elemente der ersten zugreifen. dass die Klasse.“ als Objekt der Klasse K.“ • Beispiel2: Es seien zwei Klassen definiert. dann sind auch ihre Elemente konstant. Im Unterschied zu gewöhnlichen globalen Variablen ist sein Gültigkeitsbereich nur über die Klasse erstreckt. 1. o Beispiel: Innerhalb der Klassendefinition: „static int element1“. Außerhalb wird „static“ nicht benötigt. Bei der Konstruktordeklaration in der zweiten Klasse ist dann das Präfix „friend“ erforderlich. kann das Schlüsselwort „friend“ innerhalb der Klasse für die Funktionsdeklaration verwendet werden. • Statische Elementfunktionen: analog zu Datenelementen wird innerhalb der Klassendefinition bei der Deklaration bzw. Der Zugriff ist nur indirekt mittels Zeiger möglich.01 . • Typmodifikation: mutable: Sei Klasse K konstant. außerhalb „int klasse1::element1. Sie werden in der betreffenden Klasse mit dem Schlüsselwort „static“ deklariert. Klasse. Definition der Elementfunktion das Schlüsselwort „static“ als Präfix gewählt.B. Eine Spezifizierung des Gültigkeitsbereiches ist mittels „private“. ohne die Elemente der Klasse als „public“ zu spezifizieren. Daraus ergibt sich ein mögliches Problem: Wenn nämlich mehrere Klassen wechselseitig auf Elemente der anderen zugreifen sollen. „static void f( )“ . • Beispiel: innerhalb der Klassendefinition erfolgt die Deklaration der Funktion mit dem Präfix „friend“: „friend int name( typ klassen_name & objekt_name ). deren Elementfunktion die friend-Funktion ist.

. Objekt. keine Elementfunktionen. o Eine anonyme Union hat keinen Namen. C++ KOMPENDIUM 51 Rev. o Eine Union kann keine abgeleitete Klasse sein. • Bei Strukturen ist die default-Zugriffsspezifikation „public“. Beispiel: union a {float x}. o Elemente einer anonymen Union sind zwar vom Typ „public“. und keine private. Sie muss als static spezifiziert sein. noch kann aus einer Union eine Klasse abgeleitet werden. „name_klasse“ der Name derjenigen Klasse.. Spezielle Klassen • Mittels der Schlüsselwörter „struct“ (Strukturen) und „union“ (quasi übereinanderliegende Objekte im Speicher) können auch Klassenarten generiert werden. o Beispiel: Es seien “class A” und “class B” definiert.14 }. }” Hiermit sind alle Funktionen von A friend-Funktionen von B. a u2 = u1. a u1 = { 3. o Union ohne Namenangabe: Nur zum Zeitpunkt der Definition können Objekte einer namenslosen Union oder Zeiger zum Zugriff auf Objekte der Union festgelegt werden. noch über Objekte einer Klasse mit eigenen Konstrukturen verfügen. Eine Union darf über keine statischen Elemente. o Initialisierung ohne Konstruktor kann durch ein anderes Unionobjekt gleichen Typs mittels Zuweisung erreicht werden.oder protected-Elemente..oder Zeigerdefinitionen. nur direkt möglich.01 . . • Unions: Datenelemente von Unions teilen sich den Speicherbereich (der so groß ist wie das größte Element). deren Elementfunktionen friend- Funktionen werden sollen. die anonyme Union selbst aber nicht unbedingt. Bei der Definition von class B schreibt man: „class B { friend class A. Dadurch ist Zugriff auf Elemente der Unions (deren Gültigkeitsbereich der ihrer Union ist). 1. Auch hier ist die default-Zugriffsspezifikation “public”.

als wären sie in der abgeleiteten Klasse explizit als protected spezifiziert worden (d. Besitzt die abgeleitete Klasse nur eine Basisklasse. Allerdings ist deshalb der Zugriff von außen mittels einer Elementfunktionen auf diese Elemente nicht möglich.01 . }. 10. Der default-Wert bei fehlender Angabe ist „private“.1 Mit “public” abgeleitete Klassen • „public“-Ableitungen haben die Form: „class A : public B { . die die Elemente einer bereits bestehenden Klasse übernehmen und neue hinzufügen. egal auf welche Weise die Ableitung geschieht. Abgeleitete Klassen • Abgeleitete Klassen sind solche. können aber von dieser nicht direkt erreicht werden (außer mithilfe einer friend- Deklaration in der Basisklasse). }. wie die Ableitungen vonstatten gehen kann: „public“. andernfalls von mehrfacher..“ public.h.. 10. „protected“ oder „private“. • Von der Basisklasse vererbte private-Elemente sind auch in der abgeleiteten „private“. • Allgemein gibt es drei Möglichkeiten. sind in der abgeleiteten Klasse auch ohne explizite Spezifikation wieder public. o Ebenfalls verhalten sich public-vererbte protected-Elemente so.2 Mit “protected“ abgeleite Klassen • „protected“-Ableitungen haben die Form: „class A : protected B { .. Die Angaben in eckigen Klammern sind hier optional. • Abgeleitete Klassen folgen der Syntax: class (oder struct) name_abgeleitete_klasse : [ zugriffsspezifizierer ] name_basisklasse [ weitere_zugriffsspezifizierer_und_basisklassen ] { // Spezifikation der neu hinzugekommenen Klassenelemente }. o Private-Elemente sind auch in der abgeleiteten Klasse private. spricht man von einfacher Vererbung. nur Elementfunktionen ihres „Blocks“ oder friend-Funktionen der Klasse oder ihre Ableitungen können darauf zugreifen.“ In der Basisklasse als „public“ spezifizierte Elemente. • Der Zugriffsspezifizierer beeinflusst nicht die Vererbbarkeit. 10. sondern den Zugriff auf die Elemente. die über „public“ abgeleitet worden sind.oder protected-Elemente der Basisklasse erhalten in der abgeleiteten den Status „protected“. 1. C++ KOMPENDIUM 52 Rev.. Eine abgeleitete Klasse ist also eine Spezialisierung einer Klasse.

. Klasse public public public protected protected private private (nicht zugreifbar) protected public protected protected protected private private (nicht zugreifbar) private public private protected private private private (nicht zugreifbar) 10. muss der Zugriff entsprechend qualifiziert werden. und nicht umgekehrt. • Für public-abgeleitete Elemente (oder auch Zeiger oder Referenzen auf solche) wird eine implizite Konvertierung durchgeführt.3 Mit “private” abgeleitete Klassen • „private“-Ableitungen haben die Form: „class A : private B { . 10.01 . }. mit Basisklassenname und Bereichszugriffoperator) „B::y“ angegeben wird. C++ KOMPENDIUM 53 Rev. Hier eine Übersicht über die Möglichkeiten von Ableitungen: Ableitung Element in der Basisklasse Element in der abg. wo ein Objekt (oder ein Zeiger darauf) der Basisklasse benötigt wird. wird der Zustand auf den der Basisklasse (hier protected) geändert. Deshalb kann überall.h. Klasse A die abgeleitete. • private-Elemente sind auch nach der Ableitung private – es kann nicht direkt auf sie zugegriffen werden. jedoch wird nur das Objekt der abgeleiteten Klasse in ein Objekt der Basisklasse konvertiert. Wenn auf die überdeckten Elemente (also die der Basisklasse) zugegriffen werden soll. Wenn nun x in B als „protected“ spezifiziert ist. auch ein Objekt der abgeleiteten Klasse verwendet werden.4 Redefinition von Zugriffsrechten/Konvertierung • Eine Redefinition ist eine Rücksetzung der Zugriffsrechte auf den Status in der Basisklasse. außer mithilfe einer friend-Deklaration in der Basisklasse..“ public. Beispielsweise ist Klasse B die Basisklasse. ist x nach einer „private“-Ableitung eigentlich vom Typ „private“. • Derselbe Vorgang ist natürlich auch für Funktionen möglich. Wenn allerdings mittels qualifiziertem Namen (d. • Im Falle einer Namensüberdeckung wird auf das nichtvererbte Element zugegriffen (wobei die Definitionen der gleichnamigen Elemente nicht identisch sein müssen).oder protected-Elemente erhalten durch die private-Ableitung den Status „private“. 1. jedoch nicht umgekehrt). (Weil die abgeleitete Klasse alle Elemente der Basisklasse beinhaltet.

6 Virtuelle Funktionen • Virtuelle Funktionen sind z. Basisklassen-)destruktor. Ableitungs-)konstruktor im Gegensatz zu (Ableitungs-. o Virtuelle Funktionen werden mit dem Schlüsselwort „virtual“ definiert. dann die Konstruktoren der Elementobjekt-Klassen. Andernfalls ist eine explizite Definition eines Zuweisungsoperators für die abgeleitete Klasse nötig. Eine Klasse mit virtueller Funktion nennt man auch eine polymorphe Klasse. Eine Definition ist aber nur innerhalb der Klasse möglich. kommt es zur Fehlermeldung. • Destruktoren werden ebenfalls nicht vererbt.B. Für einen fehlenden Zuweisungsoperator der abgeleiteten Klasse wird der der Basisklasse aufgerufen. o Der Standardkonstruktor der Basisklasse wird innerhalb der abgeleiteten Klasse automatisch verwendet. o Wenn eine virtuelle Funktion in einer abgeleiteten Klasse in Parametern und Rückgabewert mit der virtuellen Funktion der Basisklasse übereinstimmt. o Allerdings müssen nicht die von der Basisklasse geerbten Objekte wieder mittels des Konstruktors der abgeleiteten initialisiert werden – das erledigt der Konstruktor der Basisklasse (ein expliziter Aufruf ist natürlich trotzdem möglich). • Konstruktoren dürfen nicht vererbt werden – die Objekte der abgeleiteten Klasse sollen nämlich nicht mit Basisklassenobjekten initialisiert werden. Die Reihenfolge ist: (Basis-. 1. o Die Löschung von Elementobjekten übernimmt der Elementobjekt-Klassen- Destruktor (Aufruf wieder durch durch den Destruktor der abgeleiteten Klasse) o Der Aufruf der Destruktoren ist umgekehrt zum Aufruf der Konstruktoren. o Konstruktoren werden zur Erzeugung von Objekten abgeleiteter Klassen in folgender Reihenfolge aufgerufen: Zuerst der Konstruktor der Basisklasse(n).5 Nichtvererbbare Klassenelemente • friends: Eine als friend einer Klasse deklarierte Funktion ist nicht automatisch auch friend einer aus ihr abgeleiteten Klasse. 10. Für Basisklassenteil einer abgeleiteten Klasse ist der Basisdestruktor zuständig (Der Aufruf erfolgt durch den Destruktor der abgeleiteten Klasse). o Konstruktoren: wird eine virtuelle Funktion innerhalb einer abgeleiteten Klasse mit dem Konstruktor der Basisklasse aufgerufen.B.01 . C++ KOMPENDIUM 54 Rev. aber es kann darauf nicht ohne weiteres zugegriffen werden. wird die Version der Basisklasse ausgeführt. nur der Rückgabewert unterschiedlich ist. 10. Mittels einer virtuellen Funktion kann jedoch auch auf nichtvererbte Elementfunktionen abgeleiteter Klassen über einen Basiszeiger (ohne eine explizite Konvertierung) zugegriffen werden. Wenn aber z. für folgendes Szenario nützlich: Ein Basisklassenzeiger kann zwar auf Objekte einer abgeleiteten Klasse verweisen. Nur die neu hinzugekommenen Elemente werden mittels des der abgeleiteten Klasse eigenen Konstruktors initialisiert. • Zuweisungsoperatoren werden nicht vererbt. kann das Schlüsselwort „virtual“ entfallen. Element-. und schließlich die Konstruktoren der abgeleiteten Klasse. Element-.

Konstruktoren der virtuellen Basisklassen 2. 10. Damit wird erreicht.B. • Zeiger und Referenzen auf abstrakte Klassen sind zulässig. 10.“ abgeleitet wird. z. • Eine Basisklasse kann aber auch für verschiedene Ableitungszweige gleichzeitig virtuell und nichtvirtuell sein. • Mittels abstrakter Klassen können keine Objekte erzeugt werden. auf die der Zeiger veweist. public Y“.01 . man aber in den abgeleiteten Klassen auf die virtuelle Funktion zurückgreifen will. wenn z. z. das von der Klasse X vererbt wurde. und sie sind nicht als Funktionsparameter noch als Rückgabewerte zulässig. Grades“ nur ein Satz der Elemente der Basisklasse vererbt wird. o Destruktoren können virtuell sein.“ (Objekt a der Klasse Z.X::a = 1. wenn in der Basisklassenspezifikation in der abgeleiteten Klasse virtual hinzugefügt wird. • Achtung: Mehrdeutigkeitsprobleme sind möglich.B. Hier erbt Klasse Z alle Objekte der Klasse X und der Klasse Y. die Basisklassenversion der Funktion keine Verwendung hat. mehreren davon abgeleiteten Klassen. Konstruktoren der abgeleiten Klasse C++ KOMPENDIUM 55 Rev. Konstruktoren der nichtvirtuellen Basisklassen 3. • Virtuelle Funktionen werden benötigt.B. Man qualifiziere die Namen also eindeutig. • Die Aufruf-Reihenfolge von Konstruktoren ist in einem solchen Fall: 1.B. o Beachte: Der Zugriff auf eine virtuelle Funktion hängt vom Zugriffstatus (z. dass bei einer (virtuellen) Basisklasse. „public“ oder „private“) jener Klasse ab. wird auf den Wert 1 gesetzt) • Virtuelle Basisklassen entstehen.7 Abstrakte Klassen/rein virtuelle Funktionen • Virtuelle Funktion müssen in der Basisklasse zwar deklariert. die Klassen X und Y Objekte gleichen Namens besitzen. gemäß folgender Syntax: virtual typ_rückgabewert funktionsname ( [parameterliste] ) = 0 . und dann mittels „class abgeleitet : virtual public Basis. „Z. wenn z. „class Basis.B.8 Mehrfachvererbung • Eine Klasse kann von mehreren Basisklassen abgeleitet werden. Konstruktoren der Elementobjekt-Klassen 4.“ definiert ist.B. 1. aber nicht definiert werden. „class Z: public X. und einer von den diesen abgeleiten Klasse (hier also Mehrfachvererbung) in der „abgeleiten Klasse 2. wenn z.

1. • Die Definition einer Operatorfunktion geschieht mit dem Schlüsselwort „operator“. o Es können keine neuen Operatorsymbole eingeführt werden. o Die Priorität und die Assoziativität werden durch das Überladen nicht verändert. Überlade z. Operatorfunktionen • Operatorfunktionen sind gewöhnliche Funktionen in anderer Notation. „sizeof“ „*“ und „?“. aber ohne „klasse::“ o Als globale Funktion: typ_rückgabewert operator symbol ( klasse [&] par_name ) { anweisungen } • Nach der Definition der Operatorfunktion ist eine Deklaration innerhalb der Klasse notwendig.1 Operatorfunktionen für unäre Operatoren • Nichtstatische Elementfunktionen oder Funktionen. Die Operatoren „=“. können mittels folgender Syntaxen zum Überladen eines Operators verwendet werden: o Für Elementfunktion außerhalb der Klasse: typ_rückgabewert klasse:: operator symbol ( ) { anweisungen }“ o Für Elementfunktion innerhalb der Klasse haben sie identische Syntax. „->“ und der „cast“-Operator müssen als nichtstatische Elementfunktionen angewandt werden. 11. 11. • Grundsätzliche Regeln für Operatorfunktionen: o Eine Operatorfunktion ist stets klassenbezogen – entweder ist sie eine nichtstatische Elementfunktion (außer new und delete. Referenz auf Klasse besitzt.B. die als Parameter eine Klasse oder eine Referenz auf eine Klasse haben. von denen mindestens einer eine Klasse oder eine Referenz auf eine Klasse sein muss. „( )“. „==“ mittels „operator==“.B. Bis auf wenige Ausnahmen sind Operatorfunktionen überladbar. „[ ]“. o Für Parameter können keine default-Werte vereinbart werden. Sie sind grundsätzlich vordefiniert in Bezug auf ihre Operanden (z. denn diese sind statisch) oder eine globale Funktion.2 Operatorfunktionen für binäre Operatoren • Hier ist eine Operatorfunktion entweder eine nichtstatische Elementfunktionen mit einem (sichtbaren) Parameter oder eine globale Funktion mit zwei Parametern. die als Parameter eine Klasse bzw. Ebenfalls wird die Operandenzahl nicht verändert (außer bei new und delete). Nicht überladbar sind: „::“. 11. „. C++ KOMPENDIUM 56 Rev.01 .“. dürfen nach „==“ keine Strings stehen.

für eine Klasse class1 nach Definition „class1 a. Zuweisungsoperatoren) Element- Operatorfunktionen verwendet. nur ohne „klasse::“.“ und „strg x.“ möglich wird. die die Operanden nicht verändern.“ die Zuweisung „b = a. für das die Operatorfunktion aufgerufen wird.“ durch die Zuweisung „y = x.01 .“ ) möglich. muss der Zuweisungsoperator entsprechend überladen werden. also ein L-Wert sein). obwohl er z.2 Der Index-Operator “ [ ] “ • Der Index-Operator wird mit folgender Syntax verwendet: „Operand1 [ Operand2 ]“.B. b. die ihren linken Operanden modifizieren (z.B. Er kann nur als nichtstatische Elementfunktion verwendet werden (d. char *string = . y. d. die Operatoren +..B.h. typ par_name2)“ anzugeben.. der linke Operand ist ein Klassenobjekt). unsichtbaren Parameter den this-Zeiger. die Speicherbereiche aber getrennt belassen werden). beide verweisen danach auf denselben Speicherbereich (also eine „flache Kopie“). der auf das Objekt verweist.3 Der Zuweisungsoperator “ = ” • Der Compiler erzeugt implizit den default-Zuweisungsoperator „=“.operator [ ] (Operand2)“. so dass z. / oder == und !=. *.h. • Als Elementfunktion außerhalb der Klasse ist folgende Syntax zu verwenden: typ_rückgabewert klasse:: operator symbol (typ par_name { anweisungen } • Als Elementfunktion innerhalb der Klasse oder globale Funktion ist die Syntax identisch.B. • Äquivalent dazu ist der explizite Aufruf mit: „Operand1. Zusätzlich ist als globale Funktion „(typ par_name1. • Die Elementfunktion hat als ersten. Wenn eine „tiefe Kopie“ erstellt werden soll (so dass alle Werte kopiert. • Allgemein gilt: Es existieren globale Funktion für Operatoren (bei denen der linke Operand nicht unbedingt ein Klassenobjekt ist). dass Konstruktor der Klasse gleichzeitig ein Konvertierungskonstruktor ist und dafür bestimmte Regeln festliegen) Wenn dies nicht so sein soll. -. 11. mittels des „+“-Operators zu einem solchen hinzu summiert werden kann.B. ist eine Verkettung (z. 11. Allerdings muss der linke Operand ein Klassenobjekt sein ( was daran liegt. • Wenn aber beispielsweise vorher definierte Klassen Zeiger auf dynamisch allokierte Speicherbereiche beinhalten (z. Dagegen werden gewöhnlich für Operatoren. (d. ) wird nach „class strg. für die dann keine implizite Konvertierungsregel gilt. o Wenn der Zuweisungsoperator mit return(*this) angegeben wird.B. der linke Operand muss ein Klassenobjekt. • Nur für den Fall der Elementfunktion gilt: Hierbei kann der rechte Operand kein Klassenobjekt sein.h.“ nur die Anfangsadresse von x ins Anfangselement von y kopiert. o Für ein Überladen des „=“-Operators zum Zwecke einer Erstellung einer tiefen Kopie muss dies in der Form einer nichtstatischen Elementfunktion geschehen. muss eine globale Funktion definiert werden. 1. „a = b = c. C++ KOMPENDIUM 57 Rev. wie z.

11.3 Der Funktionsaufruf-Operator “ ( ) “

• Der Funktionsaufruf-Operator kann nur als nichtstatische Elementfunktion überladen
werden (d.h. der linke Operand ist ein Klassenobjekt).
• Dies geschieht gemäß der Syntax: „objekt ( [ ausdruck1, ausdruck2, ... ] )“. Eckige
Klammern signalisieren hier optionale Einträge.
• Äquivalent sind z.B. “X(a1, a2)” und die expliziten Schreibweise „X.operator ( ) (a1,
a2)“.

11.4 Der Pfeiloperator “ -> “

• Der Pfeiloperator, der für Zugriff auf Klassenelemente sorgt, wird als unärer Operator
interpretiert. Es ist allein die Verwendung als nichtstatische Elementfunktion ohne
Parameter möglich.
• Diese folgt der Syntax: „objekt -> element“. Hier ist die Angabe von „element“ nur aus
syntaktischen Gründen notwendig – „element“ ist kein Operand des Operators.

11.5 Die Operatoren new und delete

• Diese Operatoren lassen sich nicht nur für eine bestimmte Klasse, sondern global
überladen – damit ist die Anwendung auf beliebige Datentypen möglich.
• Es ist ebenfalls nicht unbedingt notwendig, dass mindestens ein Parameter ein
Klassenobjekt ist.
• Auf jeden Fall ist die Überladung mit statischer Elementfunktion – und damit auch der
Parameter „static“ – nicht notwendig.
• new folgt der Syntax:

void* operator new ( size_t objektgroesse [ , ...] );

Dies gibt stets einen Zeiger des Typs void zurück. Eckige Klammern signalisieren
optionale Formalparameter.
o Dynamische Objekt-Arrays allokieren: dies geschieht normalerweise mittels des
default-new-operator. Bei manchen Compilern kann man dennoch den new-
Operator überladen: z.B. mit

void* class1::operator new[] (size_t arraygröße);

o Weitere Parameter für new: Wenn zusätzlicher Formalparameter für new
angegeben werden (mittels des Schemas „typ par2, typ par2, ...“), müssen beim
Aufruf Aktualparameter angegeben werden.
• delete: beim Operator „delete“ ist ein Rückgabewert vom Typ void vorgeschrieben. Der
erste Formalparameter ist ein Zeiger vom Typ void* , möglicher zweiter Formalparameter
ist size_t . Dies ergibt die Syntax:
C++ KOMPENDIUM 58
Rev. 1.01

void operator delete ( void* objekt_zeiger [ size_t groesse ] );

Angaben in eckigen Klammern sind optional.
• new und delete global überladen: hierfür gelten die gleichen Verwendungsregeln wie
für das lokale Überladen, nur darf kein zweiter Formalparameter bei delete angegeben
werden.

11.6 Der cast-Operator/Konvertierungsoperatoren

• Die Konvertierung eines Klassenobjekts in einen anderen Typ erfolgt mittels Überladung
des cast-Operators.
• Er wird als nichtstatische Elementfunktion ohne einleitende Typangabe und ohne
Parameter verwendet, gemäß der Syntax:

[name_klasse ::] operator typ ( ) { [ anweisungen ] return (wert); }

„typ“ bezeichnet hier den Datentyp, in den das Klassenobjekt konvertiert werden soll und
damit den Typ des Rückgabewerts. Angaben in eckigen Klammern sind optional.
• Mit Hilfe dieser Prozedur sind auch Konvertierung eines Objekts der Klasse A in eines
der Klasse B möglich.

C++ KOMPENDIUM 59
Rev. 1.01

12. Streams

• Die Stream-Bibliothek (deren ganzer Titel „Standard Stream Input/Output Library“ ist) ist
ein Teil der C++ Standardbibliothek. An der Spitze der Stream-Bibliothek steht die
Basisklasse „ios“. Davon abgeleitet sind „istream“ (Datenstromeingabe) und „ostream“
(Datenstromausgabe). Von beiden abgeleitet ist „iostream“.
• Grundsätzliche ist die Stream-Bibliothek eingeteilt in
o Allgemeine Eingabe/Ausgabe: „istream_withassign“, „iostream“ und
„ostream_withassign“ leiten sich von „istream“ und „ostream“ ab,
„iostream_withassign“ wiederum von „iostrream“.
o Daten-Eingabe/Ausgabe: „ifstream“, „iostream“, und „ofstream“ leiten sich von
„istream“ und „ostream“ ab, „fstream“ wiederum von „iostream“.
o Speicher-Eingabe/Ausgabe: „istrstream“, „iostream“, „ostrstream“ leiten sich
von „istream“ und „ostream“ ab, „strstream“ wiederum von „iostream“.

12.1 Allgemeine Ein- und Ausgabe

• Vordefinierte Stream-Objekte zur Standardein- und –ausgabe sind:
o cin: die Standardeingabe
o cout: die Standardausgabe
o cerr: die Standardfehlerausgabe
o clog: das Standardprotokoll

• Ein/Ausgabe mit Datenströmen ist grundsätzlich gepuffert, was zu einer unerwarteten
Verzögerung der Ausgabe führen kann, wenn man nicht die sog. „tied streams“ benutzt,
bei denen der Ausgabepuffer geleert wird, wenn eine Eingabe ansteht. (tied-streams sind
beispielsweise „cin“ und „cout“, aber nicht „scanf“). Abhilfe kann man schaffen durch die
ausnahmslose Verwendung von tied-streams oder durch explizites Leeren des
Ausgabepuffers eines Ausgabestreams durch den Manipulator „flush“, der z.B. nach cout
<< „ ..““ mit „<< flush;“ angefügt wird (oder: „cout << setiosflags(0x2000);“ bewirkt
wiederholtes Leeren des Ausgabepuffers. Abschalten mit „resetiosflags(0x2000)“).
• „tie“-Verbindungen werden mit dem Schlüsselwort „tie“ gesetzt. Beispielsweise bewirkt
„cin.tie(NULL);“ die Lösung von cin und cout, „cin.tie(&cout);“ bewirkt
Wiederherstellung der tie-Verbindung.
• Ein/Ausgabe benutzerdefinierter Datenobjekte: „cin >> i;“ ist äquivalent zu
„cin.operator >>(i);“, da die Operatoren „>>“ und „<<“ für die Standardtypen
entsprechend überladen sind – die Klassen „istream“ und „ostream“ beinhalten die
Deklarationen „istream& operator>>(int& i);“ (analog für ostream). Für
benutzerdefinierte Streams müssen die Operatoren „>>“ und „<<“ entsprechend
überladen werden, nach folgendem Muster:
o Für istream:

istream & operator>> (istream& istr, UDC& u)
{

C++ KOMPENDIUM 60
Rev. 1.01

der noch mittels „ein = cin. öffnungsmodus ] ). //Anweisungen return (istr). definiert „istream_withassign ein.tie(&aus). z. } o Für ostream: ostream& operator<<( ostream& ostr. • Implizites Öffnen von Datein: folgt der Syntax: klasse objektname (dateiname_string [ .B.01 .“. } • Zuweisungen: z. Eckige Klammern signalisieren optionale Angaben. ios::out). const UDC& u) { //Anweisungen return (ostr). sind die Klassen „ifstream“ und „ofstream“ notwendig.dat“. C++ KOMPENDIUM 61 Rev. „ofstream outfl („ausgabe.und Ausgabe von Daten • Um Zugriff auf eine Datei auch außerhalb des Programms zu erhalten. lässt sich die Datei „ausgabe.dat“ für die Ausgabe öffnen.“ einen Eingabestrom „ein“. dass ein Puffer für neue Ein/Ausgabe- Operatoren definiert werden muss (mittels „filebuf eingabeparamter (0).B. Allerdings ist zu beachten.  ios::binary öffnet Datei im Binärmodus (default: Textmodus) o Der default-Wert bei fehlender Angabe ist ios::out.“ 12. Außerdem ist eine tie-Verbindung zu schaffen. wenn Datei exisitert. Beide sind mittels der Include Datei „fstream.2 Ein.“).h” in den Programmkopf einzuschließen.“ mit einem Standardeingabegerät verbunden werden muss (da „ein“ sonst nicht initialisiert wäre). 1. Ein analoges Objekt „aus“ kann auch für „cout“ konstruiert werden.“ und „filebuf ausgabeparameter (1). o Folgende Öffnungsmodi sind möglich:  ios::in: Datei für Eingabe öffnen  ios::out: Datei für Ausgabe öffnen  ios:ate: Nach dem Öffnen Postition an das Dateiende setzen. mittels „ein. Der Zugriff erfolgt dann über den Befehl „outfl“. wenn Datei nicht exisitert  ios::noreplace bewirkt Fehler. Das Öffnen und Schließen von Dateien lässt sich auf mehreren Wegen erreichen. Mit dem Konstruktorparamter „öffnungsmodus“. wenn ios::out gesetzt wurde  ios::nocreate bewirkt Fehler.  ios::app: Neue Daten werden am Dateiende angefügt  ios::trunc löscht Dateiinhalt.

ios::in|ios::out).B.B. [öffnungsmodus] ).“ Bei ostream muss „const char*puffer“ angegeben werden. ios::out|ios::binary). 1. • Standardeingabe/ausgabe als Dateien: „ifstream“ und „ofstream“ haben neben Konstruktoren auch noch einen Dateideskriptor.put(Zeichen)“. ifstream ifl(„doub. der mit „fd“ aufgerufen wird. einen Absatz zur Fehlerbehandlung einzuschließen. Der Aufruf C++ KOMPENDIUM 62 Rev. ios::in|ios::binary). mit der Syntax: if(file == NULL) { cout << „Fehler!“.und Ausgabeoperationen mit Dateien sind wiederum auf mehrere Arten möglich: • Formatierte Eingabe/Ausgabe folgt dem gleichen syntaktischen Muster wie die vordefinierten Standardstreams „cin“ und „cout“. an deren Stelle jetzt Streamobjekte der Klassen „ifstream“. Durch infile. wird ein Stream-Objekt definiert. • Zeichenweise Ein/Ausgabe erfolgt mit „cin.dat“. sizeof(x)). • Implizites Schließen von Dateien: Der Destruktor der Streamklasse sorgt für ein automatisches Schließen der Datei. Beispiele: ofstream ofl(„doub. o Beim Öffnen und Schließen empfiehlt es sich.dat“.“ • Textmodus/Binärmodus: um binäre Datei zu bearbeiten. exit(1).dat“.dat“. } • Ein. o Bei fstream muss ein Öffnungsmodus angegeben werden: z.write (char* puffer. • Blockweise Ein/Ausgabe ist der Zeichenweise Ein.01 .dat“ ios::in|ios::binary). int maxzahl).read(char*)y. öffnet man sie im Binärmodus mittels „ios::binary“ Beispiel: „ifstream infile(„binary. z.open („test. o Schließen: Das Schließen eines Objekts erfolgt mit dem Befehl „objekt. Anstatt mit „objekt“ den Namen des Objekts anzugeben ist auch ein Zeiger auf das Objekt möglich.dat“). wird die Datei explizit geöffnet und mit dem Stream „infile“ verknüpft. ofl. sizeof(y)).get(line)“ und „ofl. „ofstream“ und „fstream“ stehen.open(dateiname .und Ausgabe ähnlich: Sie folgt dem Schema: „streamname. ifl.write ((char*)x.“ öffnet die binäre Datei „binary. wenn der Gültigkeitsbereich des mit ihr verknüpften Streamobjekts verlassen wird • Explizites Öffnen/Schließen von Dateien: o Öffnen: Um ein Objekt zu öffnen.close( )“ • Beispiel: durch ifstream infile. folge man der Syntax objekt. „fstream iofl („einaus.

 ostream::tellp ( ). und ein Objekt „iofl. so dass „ifstream fin (0)“ ein ifstream-Objekt „fin“ erzeugt.3 Ein.“ „fprn“ mit der Standarddruckausgabe. liefert die aktuelle Position relativ zum Dateianfang. bezogen auf den Dateianfang. setzt die Position zum Schreiben auf Byte Nummer n. liefert die aktuelle Position des Schreibvorgangs relativ zum Dateianfang.01 .und Ausgabeoperationen mit Speicherbereichen • Ein/Ausgabe mit Speicherbereichen ist mittels der Streamklassen „istream“ und „ostrstream“ möglich. den Deskriptor der mit „ifl“ verknüpften Datei. „ios::beg“).B. oder int fdc = ifl. setzt die Leseposition (Streamposition) auf das Byte Nummer n. folgt dem Muster: „dateideskriptor ifstream::fd( ) const.dat“).  ostream:seekp(streamoffs. „ofstream fout(1)“ „fout“ mit der Ausgabe.dat“ öffnungsmodus). dessen Arbeitsspeicheraddresse dem Konstruktor der Streamklasse übergeben wird. 12. und analog für ofstream. o Weitere Funktionen zum Bewegen in Dateien sind  istream::tellg( ) .B. o Eingabe setzt ein char-Array voraus. Konventionelle Alternativen sind „sprintf“ und „sscanf“ für die Ein/Ausgabe mit char- Arrays. Oder man setzt die auf Position relativ zur aktuellen Position durch „ios::cur“ oder relativ zum Dateiende mit „ios::end“. 1. Beispiel: C++ KOMPENDIUM 63 Rev. Beispiel: char name. bezogen auf den Dateianfang. Analog ist bei „ofstream ferr(2). bezogen auf Anfangspunkt p. Streamklasse fstream iofl(„datei. das mit der Standardeingabe verbunden ist.seekg“ mit der Streamposition n (z.h“ benötigt. o Standard-Dateideskriptoren exisiteren aber auch in vordefinierter Form.fd( ).B. Beispiel: Es werde definiert ifstream ifl(„test.fd( ). Dann ermittelt dateideskriptor fdc = ifl. Die Schreiboperation beginnt bei Byte mit offset offs. sowie „ofstream fprn(4). ios::seek_dir p). bzw. • Bewegen in Dateien: definiere z. für die man die Include-Datei „strstream. 0). fin >> name liest „name“ ein. Eine Konstante (z.“.  ostream::seekp( streamposition n).“ „ferr“ mit der Standardfehlerausgabe verbunden.

01 . ohne explizit den Speicherbereich anzugeben. „ends“ ist hier ein Manipulator. o Ausgabe: Beispiel: char x_alpha[32]. double e. „x“ in eine Zeichenkette und speichert diese in „x_alpha“. diesen Vorgang in eine Funktion einzubinden.23“.“ Beispiel: char *buf = oss. oss << 1234 << ends. die nach folgendem Muster konstruiert wird: „char * ostrstream::str().str( ) . 1. int x = 1234. cout << buf. char d [] = „4. Definiere Streamobjekt mittels ostrstream oss(x_alpha. Nun liest iss >> e. Beispiel: ostrstream oss. muss dieser mittels ostrstream-Funktion „str“ übergeben werden. der ein Nullzeichen an Zeichenkette anfügt. 32). konvertiert sie in double-Wert und speichert diesen in e. o Dynamische Ausgabearrays werden verwendet. Damit das übrige Programm auf Speicherbereich zugreifen kann. C++ KOMPENDIUM 64 Rev. istrstream iss(d). Es ist auch möglich. die in d gespeicherte Zahl als Eingabe. Nun konvertiert oss << x << ends.

„reinterpret_cast“ und „dynamic_cast <zieltyp> (ausdruck)“ reserviert. existieren folgende Objekte: o dynamic_cast-Operator: Mit diesem Operator lassen sich Konvertierungen zur Laufzeit eines Programmes durchführen und Prüfungen.“ ist die Verwendung des Datenobjekts im lokalen Gültigkeitsbereich in gewöhnlicher Weise und ohne Qualifizierung mit „::“ möglich. . kann man Doppeldeutigkeiten mit den „namespaces“ vermeiden.B. z. Nun greift pool1::a=3. o static_cast: ist einfaches Gegenteil der impliziten Typkonvertierung. ob Konvertierung eines Zeigers auf eine polymorphe Basisklasse in Zeiger auf abgeleitete Klasse fehlerhaft ist. das Ziel muss ein Zeiger oder eine Referenz auf eine Klasse sein. o using-Deklarationen: mittels „using name_namensbereich::elementname. „using pool::x. Spracherweiterungen • Wahrheitswerte (bool): Standardmäßig sind 0 = false und 1 = true definiert. geschrieben werden können.01 . namespace pool2{int a = 1}. • Namensbereiche: Wenn z. o Der Zugriff erfolgt mittels „name_namensbereich::name_element“. o const_cast: für Konvertierung von „const“ in nicht-„const“. Syntax: „dynamic_cast <zieltyp> (ausdruck)“. „const_cast“. C++ KOMPENDIUM 65 Rev. • Explizite Typumwandlung: für explizite Konvertierungen sind „static_cast“. o reinterpret_cast: außer bei „const“ für beliebige Typumwandlungen o dynamic_cast: führt eine Typumwandlung während der Laufzeit des Programms durch. so dass Funktionen wie bool istrue. • Laufzeit-Typinformationen: Um Zur Laufzeit eines Programmes Informationen über den Typ eines Objekt zu erhalten. in Klassen oder Include-Dateien Objekte gleichen Namens erstellt wurden. auf das Element „a“ aus „pool1“ zu und weist ihm innerhalb dieses Namensbereiches den Wert 3 zu. mit Hilfe der Syntax: namespace [name_namensbereich] {deklarationen/definitionen_der_elemente}.B. Beispiel: namespace pool1 {int a = 0}. 1. if (istrue == false) istrue = true.“ o using-Direktiven: „using namespace name_namensbereich“ macht alle Namen eines Namensbereich ohne Qualifizierung verfügbar. 13.

Außerdem ist „throw“ hilfreich.h“) zurückgegeben.. anweisungen • Ausnahmebehandlung: Die Ausnahmebehandlung geht mit den Befehlen „try“. typename typ2. wenn beispielsweise bei der Definition einer Funktion kenntlich gemacht werden soll. mit denen sich beliebig viele Varianten einer Funktion oder Klasse durch nur eine Definition erzeugen lassen. o Beispiel: template <typename T> void funktion1 (T* array1.01 .. • Templates: Es existieren Funktions.. Um das Template zu variieren (d. o try: „try { . benutze man die Syntax: „template <> funktionsdefintion“. o Funktionstemplates haben zwei mögliche Syntaxen: template <class typ [. class typ3. ]> funktionsdefinition Eckige Klammern signalisieren optionale Angaben. bei „double funktion(int x) throw(char *). .. o Klassentemplates: haben eine analoge Syntax: template <parameterliste> klassendefintion Parameter sind wieder mit „class“ oder „typename“ anzugeben. falls ein Fehler beim Öffnen der Datei durch infile auftritt.“ legt die Anweisungen fest. o throw folgt der Syntax: „throw(ausdruck). o catch folgt der Syntax: „catch (parameter) { Anweisungen }. und reagiert bzw. „throw“ und „catch“ vor sich. int x1) Nun kann „void funktion1“ für verschiedene Aufgaben benutzt werden. allerdings sind auch gewöhnliche Parameter wie bei Funktionen möglich.“ Die „catch“- Anweisung befindet sich direkt hinter dem try-Block. Beispiel der Vewendung: double d.h. bearbeitet dort entstandene Fehler. dass sie Ausnahmen produzieren kann. }... für die eine Ausnahmebehandlung durchgeführt wird.und Klassentemplates. .B. 1. if (typeid(d) == typeid(double)) . ] > funktionsdefnition oder die neuere Schreibweise mit dem Schlüsselwort „typename“: template <typename typ [. class typ2.“ einen Fehlerwert aus. zu überladen). o typeid-Operator und type_info-Klasse: Mittels „typeid (ausdruck)“ oder „typeid (typname)“ wird eine Referenz auf ein Objekt der Klasse „type_info“ (definiert innerhalb der Include-Datei „typeinfo.“ Beispielsweise gibt „if(!infile) throw 0. o Beispiel: template <typname T> class array { klassen_definition} C++ KOMPENDIUM 66 Rev. z...

Elem. Containerklassen. auf erstes Element zurück size() Gibt Anzahl der Elemente zurück maxsize() Gibt maximale mögliche Größe zurück empty() Liefert true. wenn zwei Cont. lieg. o Standard-Template-Library (STL): Sammlung von vordefinierten Templates für verschiedenste Programmbereiche. Hier eine Übersicht über die STL-Container-Funktionen (Ein Iterator ist ein Zeiger af Element eines Containers): begin () Liefert Iterator auf erstes Element zurück end() Liefert Iterator auf hinter dem letzten Element liegendes Element zurück rbegin() Liefert rückwärts zählenden Iterator auf hinter dem letzt.“ eine Klasse „array <int>“ und definiert ein Objekt a dieser Klasse. die lgeiche Größe und Elemente haben logisch: != Gegenteil < Liefert für (a<b) true zurück. falls Container leer. 1. It. Dann generiert „array <int> a(10). sonst false Swap() vertauscht Inhalt zweier Container logisch: == liefert true. wenn a lexikografisch vor b > Analog <= Analog >= Analog • C++-Präprozessor: Es existieren die folgenden Präprozessor-Anweisungen: #include #define #undef #if #elif #else #endif #ifdef #ifndef #error #line #pragma C++ KOMPENDIUM 67 Rev.B. hier z.01 . Element zurück rend() Liefert rückwärts zähl.

B. o Klammern für (a) und (b) sind im Ersatztext notwendig. um Fehler zu vermeiden. Eckige Klammern signalisieren optionale Elemente (d.01 . o Makros löschen: geschieht nach folgendem Schema: „#undef makro_name“ o Bedingte Kompilierung: mittels verschiedener Direktiven von „#if“ bis „#ifndef“ lässt sich ein Teil des Programms nur dann kompilieren.1) summiert 1+1. und lediglich als Platzhalter für die Werte dienen.h. o Präprozessor-Anweisungen können an beliebiger Stelle stehen. Hier sind a und b Aktualparameter. o Include-Dateien: Syntax: #include <Dateiname> oder #include „Dateiname“ o Symbolische Konstanten: definiere Konstanten aus Gründen der Übersichtlichkeit vor dem Programm mit „#define name_der_konstanten [text]“. o Makros mit Parameter: haben die Syntax: #define makro_name(par1. o Beispiel: #define NL cout << „\n“ bewirkt einen Zeilenvorschub im Programm überall da.b) (a) + (b). eine #define-Anweisung ist auch ohne Ersatztext möglich.B. o Mittels „#undef name_der_konstanten“ kann die Definition rückgängig gemacht werden. die nicht eigens definiert werden müssen. Dies geschieht mittels der Syntax: #if konstanter_ausdruck programmteil [#elif konstanter_ausdruck programmteil #elif konstanter_ausdruck programmteil …. o Makros ohne Parameter: folgen der Syntax: „#define makro_name text“. summe(1.B. z. wenn eine bestimmte Bedingung (true) erfüllt ist. z. par2. meist werden sie jedoch an den Anfang gesetzt. „#define PI 3. also z.1415“ (Die Kreiszahl π). weil ein Makro eine Operation repräsentiert und eine symbolische Konstante eine nichtoperative Zeichenfolge darstellt. die dann im Programm mit dem Makro verwendet werden. o Makros: Beispiel: „#define TOP 8“. Dennoch besteht ein Unterschied. wo „NL“ steht. Manchmal wird in der C++-Literatur kein Unterschied zwischen Makro und symbolischer Konstante gemacht. 1. #else programmteil ] C++ KOMPENDIUM 68 Rev. Mit „text“ wird eine oder mehrere Operation(en)/Anweisung(en) repräsentiert. #define fehler (wird wegen fehlenden Ersatztextes an allen Stellen ihres Auftretens im Porgramm entfernt). …) text o Beispiel: #define summe(a.

„konstanter_ausdruck“ ist hier die Bedingung: wenn diese ungleich Null ist. o Pragmas: Pragmas sind Compiler-Direktiven. werden die Anweisungen des zugehörigen „programmteil“s kompiliert.01 . __FILE__ Stringkonstante. die die die Uhrzeit der letzten Kompilierung angibt. dass der betreffende Teil nicht unbedingt nötig ist. die anderen werden aus dem Quellcode gelöscht. __cplusplus Ist definiert.B.. Wenn diese Konstanten in den Quellcode (mit z. die die Nummer der aktuellen Zeile im Quelltext angibt.] #endif Nur wenn „symb_konst“ definiert ist. wird „programmteil“ ausgeführt.. vergleichbar mit Compiler- Optionen. 1. die den Namen der aktuellen Quelldatei angibt. __TIME__ Stringkonstante. wenn ein C++-Programm kompiliert wird. Die Verfügbarkeit von Pragmas ist Compiler-abhängig. Alternative Schreibweise: “#if defined” entspricht “#ifdef”. “#if !defined” enspricht “#ifndef” o #error: hat die Syntax: „#error: Message“. Beispielsweise kann mit dem MS-C++ Compiler während Kompilierung mit „#pragma message(„text“)“ eine Botschaft „text“ ausgegeben werden. #endif Die Klammern „[ ]“ deuten an. Der Befehl gibt „Message“ aus und bricht den Kompiliervorgang ab. cout) integriert werden. die das Datum der letzten Kompilierung angibt. __DATE__ Stringkonstante. o Präprozessorkonstanten: Konstante Bedeutung __LINE__ Ganzzahlige Dezimalkonstante. C++ KOMPENDIUM 69 Rev. werden die jeweiligen Daten über das Programm ausgegeben. Die Syntax ist denkbar einfach: „#pragma instruktion“. o defined-Operator: “#ifdef” und “#ifndef”: haben die Syntax: #if defined (symb_konst) programmteil [#elif defined (symb_konst) programmteil .