Literale Konstanten
Konstanten sind Bezeichner mit einem festen Wert. In C++ hat jede Konstante
auch einen bestimmten Typ, wobei sich der Typ schon eindeutig aus dem Wert
der Konstanten ergibt, z.B. wird eine Konstante mit dem Wert 53421 als
Integer-Konstante erkannt, ABcDef als Zeichenfolgen-Konstante usw.
In diesem Kapitel geht es darum, wie und in welcher Form Konstanten
bestimmter Datentypen anzugeben sind. C++ kennt für die Werte elementarer
Typen jeweils eine eigene Notation, auf die an dieser Stelle näher
eingegangen werden soll:
-
Integer-Konstanten
-
Fließkomma-Konstanten
-
Textzeichenkonstanten
-
String-Literale
-
Die Null
Darüberhinaus kennt C++ auch
Eine symbolische Konstante stellt dabei einen Namen dar, dessen Wert innerhalb
seines Bezugsrahmens nicht veränderbar ist.
Integer-Konstanten
Bei Integer-Konstanten können insgesamt vier Formen auftreten:
-
dezimale Konstanten
-
oktale Konstanten
-
hexadezimale Konstanten
-
Textzeichenkonstanten
Während dem letzten Punkt ein eigener Abschnitt gewidmet ist, befassen
wir uns hier mit den drei erstgenannten.
Unabhängig von der Darstellungsart hängt der Typ einer angegebenen
Integer-Konstanten, wenn er nicht explizit vorgegeben wird, von der Größe
der Konstanten ab. Standardmäßig ist die Konstante vom Typ int,
solange der Wert in ein int-Objekt paßt, andernfalls long.
Sollte die Konstante auch für long zu groß sein,
so sollte der Compiler eine Warnung ausgeben.
Dezimale Angabe
Dezimale Konstanten werden wohl am häufigsten verwandt, da sie auch
im "Alltagsleben" gebräuchlich sind:
2 12345 98773
22677672787189891
Oktale Angabe
Eine Konstante, die mit einer 0 beginnt, wird als Oktalzahl,
d.h. eine Zahl zur Basis 8, interpretiert:
06 033 040
(entsprechen dezimal: 6, 27, 32)
Hexadezimale Angabe
Eine Konstante , die mit 0x beginnt, wird als Hexadezimalzahl,
d.h. eine Zahl zur Basis 16, interpretiert:
0x6 0x1B 0x20
(entsprechen dezimal: 6, 27, 32)
Die Buchstaben a, b, c, d, e, f bzw. A, B, C, D, E , F repräsentieren
dabei die Ziffern 10, 11, 12, 13, 14 und 15.
Festlegung des Integer-Typs:
Zusätzlich zu diesen drei Darstellungsmöglichkeiten kann man,
falls notwendig, den Integer-Typ durch das Anhängen von einem oder
zwei der folgenden Buchstaben weiter detaillieren:
-
u oder U (unsigned) für Integer-Konstanten ohne
Vorzeichen
-
l oder L (long) für lange Integer-Konstanten
Beispiel:
Fließkomma-Konstanten
Fließkomma-Konstanten sind standardmäßig vom Typ double.
Die Darstellung von Fließkommakonstanten sollte als bekannt gelten,
so daß einige Beispiele genügen:
// Dezimalzahl mit Punkt:
3.1471 .75
6.
// Eine Ganzzahl mit Exponenten e oder E:
4E8 5e2 9e-23
// Kombination aus beiden Alternativen:
0.782e-8 1.2E14
Man beachte lediglich, daß innerhalb der Fließkomma-Notation
keine Leerzeichen auftreten dürfen.
Durch das Anhängen der Buchstaben f bzw. F entsteht
eine Konstante vom Typ float, durch das Anhängen der Buchstaben
l bzw. L entsteht eine Konstante vom Typ long double
3.1416 // double-Konstante
3.1415926356f // float-Konstante
3.14L
// long double-Konstante
Textzeichenkonstanten
Textzeichenkonstanten (Character-Konstanten) werden als Zeichen des verwendeten
Zeichensatzes notiert, das in einzelne Anführungsstriche (Apostrophe)
eingeschlossen ist:
Solche Textzeichenkonstanten sind eigentlich symbolische Integer-Konstanten,
deren Wert sich aus der Ordnungszahl des Zeichens in der Code-Tabelle des
verwendeten Zeichensatzes ergibt (auf einer Maschine mit ASCII-Zeichensatz
hat z.B. das Leerzeichen den 32, im EBCDIC-Code den Wert 64) .
Eine Character-Konstante ist also stets vom Typ int.
Einige wenige Zeichen, die sogenannten Escape-Sequenzen, haben Standardnamen
mit einem Backslash als Fluchtsymbol.
'\a' BEL
alert
'\b' BS
backspace
'\f' FF
form feed
'\n' NL(NF) newline
'\r' CR
carriage return
'\t' HT
horizontal tab
'\v' VT
vertical tab
'\\' \
backslah
'\'' '
single quote
'\"' "
double quote
'\?' ?
question mark
'\0' NUL
integer 0
'\ooo' ooo
octal number
'\xhhh' hhh hex
number
Trotz der Schreibweise handelt es sich jeweils nur um ein Zeichen. Textzeichenkonstanten
können auch hexadezimal oder oktal dargestellt werden, indem \x
bzw. \ einer ein- bis dreistelligen Zahl vorangestellt wird:
'\60' '\x30' 48
ASCII: '0'
'\137' '\x05f' 95
ASCII: '_'
String-Literale
Eine Zeichenfolgen-Konstante (String-Konstante) ist ein (möglicherweise
leere) Sequenz von Zeichen, die in doppelten Anführungszeichen eingeschlossen
ist. Escape-Sequenzen (vgl. Textzeichenkonstanten) für Zeichen sind
innerhalb der Zeichensequenz zulässig:
"Dies ist eine String-Konstante mit Escape-Sequenz \n"
Der Typ eines String-Literals ist dabei ein char-Array angemessener
Länge (inklusive der terminierenden Null!).
Die Zeichenfolge "Zeile" wird auf sechs aufeinanderfolgende
Speicherzellen abgelegt:
Lange String-Literale dürfen und sollten der besseren Lesbarkeit des
Programms wegen auf mehrere Zeilen verteilt werden, wobei jedoch echte
Zeilenvorschübe im Programmtext nicht Bestandteil eines String-Literals
sein dürfen:
char str_1[]= "Dies ist kein String
sondern ein Syntax-Fehler"
char str_2[]= "Dieser lange String ist korrekt ueber mehrere"
"Zeilen verteilt worden, um die Lesbarkeit zu erhoehen."
Die Null
Eine besondere Rolle nimmt die Null(0)-Konstante ein, die als Pointer-Konstante
für beliebige Pointer-Typen verwandt werden kann.
Null(0) ist vom Typ int. 0 kann wegen der automatischen Typumwandlung
auch als Konstante eines anderen Integer-, Fließkomma- oder Zeigertyps
verwendet werden. Speziell auf Zeiger bezogen bezeichnet 0 den leeren Zeiger
(NULL-Zeiger).
Bei der Adresse 0 ist nie ein Objekt allociert, und der Typ von Null
ist vom Kontext abhängig.
Symbolische Konstanten
Bei den symbolischen Konstanten unterscheidet C++ drei Arten:
-
Benannte Konstanten
-
Aufzählungen
-
Jeder Array- oder Funtkionsname ist eine Konstante
Benannte Konstanten:
Benannte Konstanten erhält man, indem man bei der Deklaration eines
Objektes bzw. eines Typs das Schlüsselwort const hinzufügt.
Dadurch wird das Objekt nicht als Variable, sondern als Konstante spezifiziert:
const int wert = 15;
const v[] = { 1 ; 2 ; 3 ; 4};
Da es zu den Eigenschaften einer Konstanten gehört, daß dieser
kein Wert zugewiesen werden kann, muß eine Konstante auch gleich
bei der Deklaration wie im Beispiel initialisiert werden. Ein nachträgliche
Veränderung innerhalb ihres Bezugsrahmens ist dann nicht mehr möglich:
wert +=40; // FEHLER
wert--; // FEHLER
Es sei darauf hingewiesen, daß das Schlüsselwort const
die Zugriffsrechte auf ein Objekt und damit den Typ des Objektes verändert.
Die Art der Allokation des Objektes wird dadurch jedoch nicht beschrieben;
das Ausnutzen der Zusatzinformation des Konstantseins bleibt jedem Compiler
selbst überlassen.
"konstante Pointer"
Ein besonderes Problem tritt bei der Verwendung von Pointern (Zeigern)
auf. Hier muß nämlich unterschieden werden, ob der Pointer selbst
oder aber das Objekt, auf das er zeigt, konstant sein sollen. Bei einem
Pointer sind ja grundsätzlich immer zwei Komponenten beteiligt:
-
der Pointer selbst und
-
das Objekt, auf das gezeigt wird.
Wird bei einer Pointer-Deklaration das Schlüsselwort const
vorangestellt, so wird zwar das Objekt, nicht aber der Pointer konstant
gemacht:
const char* char_pointer = "konstant"; // Pointer
auf eine Konstante
char_pointer[6] = 'u';
// FEHLER, da Objekt konstant!
char_pointer = "variabel";
// Okay
Um hingegen den Pointer selbst konstant zu machen, nicht jedoch das Objekt,
auf das er zeigt, muß der Operator *const verwendet werden:
char *const char_pointer = "konstant";
// konstanter Pointer
char_pointer[6] = 'u';
// Okay
char_pointer = "variabel";
// FEHLER
Um nun beide Komponenten, d.h. sowohl den Zeiger als auch das Objekt, konstant
zu machen, bedarf es der Verwendung zweier consts:
const char *const char_pointer = "konstant";
// konstanter Pointer auf eine Konstante
char_pointer[6] = 'u';
// FEHLER
char_pointer = "variabel";
// FEHLER
Da Pointern noch ein eigenes Kapitel am Ende dieses Kurses gewidmet ist,
sollen die Beispiele für einen ersten Einblick genügen.
Aufzählungen
Eine Aufzählung (Enumeration) ist eine Menge von Integer-Konstanten
und stellt eine bequemere Alternative zum Benennen einzelner Integer-Konstanten
dar.
Der Aufzählungstyp wird mit dem Schlüsselwort enum (für
enumerate) definiert, gefolgt von einer durch Kommata abgetrennten Liste
von Bezeichnern, die in geschweiften Klammern angegeben werden:
enum name_opt { bezeichner_0, bezeichner_1,
..., bezeichner_n};
Wie in der Syntax erkennbar, kann man einer Aufzählung auch einen
Namen name_opt geben, der dann einen neuen Typ / ein neues
Objekt bezeichnet.
Die Zuordnung von Integerwerten und damit der Wert der Aufzählungskonstanten
ergibt sich aus der Reihenfolge ihrer Angabe, beginnend mit dem Wert 0.
Beispiel:
enum Tage {Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag,
Sonntag};
ist gleichbedeutend mit den Deklarationen
const Montag = 0;
const Dienstag = 1;
const Mittwoch = 2;
...
const Sonntag = 6;
Die Elemente des Aufzählungstyps sind dabei die einzigen Werte, die
diesem zugewiesen werden dürfen. Ferner ist zu beachten, daß
Werte des neuen Typs über implizite Typumwandlung an Integer-Variablen
zugewiesen werden können, die umgekehrte Zuweisung jedoch einer expliziten
Typumwandlung bedarf. Der Grund ist der, daß die meisten Integer-Werte
in der jeweiligen Aufzählung gar nicht repräsentiert sind und
es so zu nicht vorhersehbaren Zuweisungen kommen würde.
void main()
{
Tage heute = Mittwoch;
int k = Samstag;
heute = k;
// FEHLER
heute = Tage(k); // Okay, da explizite
Typumwandlung
k = heute;
// Okay
heute = 8;
// FEHLER
}
Die Vorteile des Einsatzes von Aufzählungen liegen auf der Hand:
-
Zum einen unterstützt die Deklaration eines Aufzählungstyps die
Überprüfung, ob dem Typ auch tatsächlich nur die Werte zugewiesen
werden, die auch zulässig sind, und zum anderen
-
sind die Definitionsbezeichner eine Hilfestellung in der Dokumentation
(dies natürlich nur, wenn man den Bezeichnern auch wirklich sinnvolle
Namen gibt).