Teil 1: Grundlagen


Daten

Variablen

Veränderbare Daten werden in Variablen abgelegt. Da es unter C++ keine automatische Definition von Variablen gibt, müssen diese explizit definiert werden:

DTYP NAME;

DTYP bestimmt den Datentyp der Variable und NAME ist der Name, über den auf den Inhalt der Variable zugegriffen wird. Der Name muss eindeutig sein, d.h. es darf keine zweite Variable (oder Funktion und Ähnliches) mit gleichem Namen im gleichen Gültigkeitsbereich geben. Was Gültigkeitsbereiche sind, wird in einem späteren Kapitel erklärt.

Datentypen

C++ kennt folgende Datentypen für ganze Zahlen, auch Integer-Zahlen genannt:

signed char
unsigned char
signed short int
unsigned short int
signed int
unsigned int
signed long int
unsigned long int
signed long long int
unsigned long long int

Variablen vom Typ unsigned können nur positive Werte (einschließlich der 0) annehmen, wogegen die signed Datentypen sowohl positive wie auch negative Werte annehmen können.

Bei den Datentypen short, long und long long kann die Angabe von int und signed (aber nicht unsigned!) auch entfallen, d.h. anstelle signed short int kann lediglich short stehen.

Der Unterschied zwischen den einzelnen Datentypen liegt im Wertebereich, den eine entsprechende Variable aufnehmen kann. Die Sprache C++ schreibt die Wertebereiche der Datentypen nicht explizit vor, jedoch muss immer folgender Zusammenhang gelten:

signed char
=
1 Byte
signed char
<=
short
short
<=
int
int
<=
long
long long
>=
64 Bit

In der nachfolgenden Tabelle sind einmal die jeweiligen Wertebereiche der signed Datenypen des MinGW Compilers sowie des Visual Studio Compilers aufgeführt.

Datentyp
Wertebereich
signed char
-128...127
short
-32768... 32767
long
-2147483648...2147483647
long long
-9223372036854775808...9223372036854775807

Die Wertebereiche der unsigned Datentypen ist dementsprechend MAXVAL - MINVAL, d.h. der unsigned short Datentyp hat dann z.B. einen Wertebereich von 0...(32767 - -32768), gleich 0...65535.

Für die Verarbeitung von Gleitkommazahlen stehen 3 verschiedene Datentypen zur Verfügung: float, double und long double. Diese Datentypen unterscheiden sich zum einen im darstellbaren Wertebereich und zum anderen, was fast noch wichtiger für Berechnungen ist, durch die Anzahl der Stellen, mit denen der Datentyp arbeitet.

Datentyp
Min
Max
Berechnung 1/3
float
1.17549e-38
3.40282e+38
0.3333333432674407959
double
2.22507e-308
1.79769e+308
0.33333333333333331483
long double
3.3621e-4932
1.18973e+4932
0.33333333333333333334

Zum Abspeichern von Zeichen werden die Datentypen char und wchar_t verwendet. Der Datentyp char dient zur Aufnahme eines 1 Byte großen Zeichens, während der Datentyp wchar_t ein Zeichen eines erweiterten Zeichensatzes aufnehmen kann.

Der Datentyp bool kann nur die beiden Zustände (Werte) true und false annehmen. Und der Datentyp void ist ein unvollständiger Datentyp, der hauptsächlich als Returntyp bei Funktionen/Memberfunktionen oder im Zusammenspiel mit Zeigern verwendet wrd. Auf ihn werden wir später zurückkommen.

Variablen können bei ihrer Definition mit einem Wert initialisiert werden. Dies erfolgt in der Art, dass nach der Definition der Variable der Zuweisungsoperator = folgt und danach der Initialwert. Außerdem lassen sich mehrere Variablen des selben Datentyps in einer Anweisung definieren. Die Variablen werden dann durch Kommas getrennt aufgelistet.

// Datei iostream einbinden
#include <iostream>
int main ()
{
    unsigned short width, height;   // 2 short Variablen definieren
    unsigned int value = 10;        // Variable definieren und mit 10 initialisieren
    unsigned xpos = 0, ypos = 0;    // 2 short definieren und initialisieren
}

Konstanten

Im Gegensatz zu Variablen können Konstanten nach ihrer Definition ihren Inhalt (Wert) nicht mehr ändern.

Literal (unbenannte Konstante)

Ein Literal ist die direkte Angabe eines Wertes, wie z.B. die Zahl 5 oder der String "Dies ist ein Literal".

Ganzzahl-Literale besitzen standardmäßig den kleinsten Datentyp, in dem ihr Wert dargestellt werden kann. Um ein Ganzzahl-Literal explizit einem Datentyp zuzuordnen, wird der Wert mit einem Präfix oder Suffix erweitert.

Binär-Literal
Präfix 0b
0b10001101
Oktal-Literal
Präfix 0
0665
Hex-Literal
Präfix 0x
0x3FC1
unsigned Literal
Suffix U
40219U
long Literal
Suffix L
8765423L
unsigned long Literal
Suffix UL
4234UL
long long Literal
Suffix LL
245LL
unsigned long long Literal
Suffix ULL
98764ULL

Gleitkomma-Literale besitzen standardmäßig den Datentyp double. Um einem Gleitkomma-Literal einen von double abweichenden Datentyp zuzuweisen, wird das Literal mit einem Suffix laut nachfolgender Tabelle erweitert.

float
Suffix F
1.3F
long double
Suffix L
3.124L

Zeichen-Literale sind einzelne Buchstaben oder auch Escape-Sequenzen, die in Hochkomma eingeschlossen werden. Sie besitzen den Datentyp char.

String-Literale werden in Anführungszeichen eingeschlossen und die einzelnen Zeichen innerhalb des String-Literals sind vom Datentyp char. Das letzte Zeichen eines String-Literals ist immer eine 0 (Null).

Selten verwendet, jedoch auch möglich: Zeichen- und String-Literale mit einem von char abweichenden Datentyp für Zeichensätze, bei denen ein Zeichen nicht in einem Byte abgespeichert werden kann. Mehr dazu im C++ Buch oder auch unter https://en.cppreference.com/w/cpp/language/types.

Benannte Konstanten

Benannte Konstanten werden prinzipiell wie Variablen definiert, d.h. sie haben einen Datentyp und einen Namen. Zusätzlich wird jedoch vor dem Datentyp das Schlüsselwort const gestellt. Und da Konstanten (ihrem Sinn nach) während des Programmlaufs ihren Wert nicht ändern können, müssen sie bei ihrer Definition initialisiert werden.

const int
LINES
= 10;
const char
ALPHA
= 'A;

constexpr Ausdruck

Der Qualifizierer constexpr weist den Compiler an, einen Ausdruck zum Zeitpunkt des Übersetzungsvorgangs auszuwerten. Kann der Ausdruck nicht während des Übersetzungsvorgangs berechnet werden, so erzeugt dies einen Fehler.

// Datei iostream einbinden
#include <iostream>
int main ()
{
    int var1 = 10;
    constexpr int const1 = 10;         // Ok
    ...                                // Hier könnte var1 verändert werden
    constexpr int const2 = 10 + val;   // Fehler, da var1 keine Konstante
}

auto Datentyp

Werden Variablen bei ihrer Definition initialisert, so kann der Compiler aufgrund des Datentyps des Initialisierungsausdruck den Datentyp der Variable bestimmen. Hierzu wird der explizite Datentyp bei der Variablendefinition durch das Schlüsselwort auto ersetzt.

// Datei iostream einbinden
#include <iostream>
int main ()
{
    auto var1 = 10;         // int Variable initialiseren
    auto var2 = 1.0f/3.0f;  // double Variable initialisieren
    auto isDone = false;    // bool Variable initialisieren
}

Referenz-Variablen

Referenz-Variablen enthalten Verweise auf bereits definierte Variablen. Um eine Referenz-Variable zu definieren, folgt nach dem Datentyp das Symbol &, dann der Name der Referenz-Variable RNAME und anschließend der Namen der Variable VNAME, auf die die Referenz verweisen soll.

DTYP& RNAME = VNAME;

Referenz-Variablen unterliegen folgenden Einschränkungen:

  • Referenz-Variablen müssen immer einen Verweis enthalten, d.h. sie müssen bei ihrer Definition initialisiert werden.
  • Nach der Initialisierung kann der Verweis einer Referenz-Variable nicht mehr geändert werden. Wird einer Referenz-Variable eine andere Variable oder eine Konstante zugewiesen, so wird der Inhalt der Variable bzw. die Konstante in die Variable übernommen, auf die die Referenz-Variable verweist.
  • Der Datentyp der Referenz-Variable muss mit dem Datentyp der Variable übereinstimmen, auf die verwiesen wird.

Mag Ihnen im Augenblick der Einsatz von Referenz-Variablen im Augenblick noch etwas unklar sein, so wird sich dies im Verlaufe des Kurses noch klären.

decltype Operator

Mit Hilfe des Operators decltype kann der Datentyp eines Ausdrucks bestimmt und damit unter anderem den Datentyp einer Variablen indirekt festlegt werden. Die allgemeine Syntax lautet:

decltype (AUSDRUCK) VARIABLE;

Je nach Typ von AUSDRUCK liefert decltype folgenden Datentyp zurück:

  • Ist AUSDRUCK eine Variable, liefert decltype den Datentyp der Variable zurück.
  • Ist AUSDRUCK eine Funktion, so liefert decltype den Returntyp der Funktion zurück (Funktionen werden später noch ausführlich behandelt). Der Returntyp der Funktion darf nicht vom Typ void sein.
  • Ist AUSDRUCK ein Ausdruck, welcher rechts vom Zuweisungsoperator = steht (auch als rvalue bezeichnet), liefert decltype den Datentyp des Ergebnisses des Ausdrucks zurück.
  • Ist AUSDRUCK ein Ausdruck, welcher links vom Zuweisungsoperator = steht (auch als lvalue bezeichnet), liefert decltype einen Referenzdatentyp zurück.
  • Wird für AUSDRUCK das Schlüsselwort auto angegeben, so liefert decltype den exakten Datentypen des rechts vom Zuweisungsoperator stehenden Ausdrucks.

// Datei iostream einbinden
#include <iostream>
int main ()
{
    short var1;
    // var2 hat stets den gleichen Datentyp wie var1
    decltype(var1) var2;
    // var3 hat den Datentyp int, da main() einen int-Wert zurueckliefert
    decltype(main) var3;}

sizeof Operator

Der Operator sizeof(ARG) liefert den von einem Datentyp oder einer Variable belegten Speicherplatz in Bytes zurück. ARG gibt den Datentyp oder die Variable an, deren Speicherbedarf ermittelt werden soll.

// Datei iostream einbinden
#include <iostream>
using std::cout;
using std::endl;

int main ()
{
    // Einige Variablen definieren
    bool boolVar;
    long longVar;
    // Von den Variablen belegten Speicher ausgeben
    cout << "bool: " << sizeof(boolVar) << endl;
    cout << "long: " << sizeof(longVar) << endl;
    // Den vom Datentyp float benötigten Speicher ausgeben
    cout << "float: " << sizeof(float) << endl;
}



Copyright © cpp-tutor.de
Impressum &Datenschutz