Für ganzzahlige Daten, auch Integer-Daten genannt, stehen die in der nachfolgenden Tabelle aufgeführten Datentypen zur Verfügung. Die Wertebereiche der Datentypen bei Verwendung des MinGW-Compilers sowie des Visual Studios sind ebenfalls aufgeführt.
Für die Verarbeitung von Gleitkommazahlen stehen 3 Datentypen zur Verfügung. Diese Datentypen unterscheiden sich zum einen ebenfalls im Wertebereich und zum anderen durch die Anzahl der Stellen, mit denen der Datentyp rechnet.
Zum Abspeichern von Zeichen wird in der Regel der Datentyp char verwendet. Er dient zur Aufnahme eines 1 Byte großen Zeichens.
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 (Member-)Funktionen oder im Zusammenspiel mit Zeigern verwendet wird. Auf ihn werden wir später zurückkommen.
Es sei an dieser Stelle darauf hingewiesen, dass es noch weitere Datentypen gibt, die erst später behandelt werden.
Veränderbar Daten werden in sogenannten Variablen abgelegt. Bei der Definition einer Variable wird zuerst deren Datentyp und anschließend der Name der Variable angegeben. Für den Augenblick ist es noch nicht relevant, ob die Definition einer Variable vor oder innerhalb der main()-Funktion erfolgt.
Der Name der Variable muss eindeutig sein und unterliegt folgenden Einschränkung:
// Header-Datei einbinden
#include <iostream>
#include <format>
// Definition einer char- und unsigned long Variable
char cvar;
unsigned long ulvar;
int main()
{
// Definition einer bool und float Variable
bool bvar;
float fvar;
// Ausgabe der Variablen
std::cout << std::format("char: {:x}, unsigned long: {}\n"
"bool: {}, float: {:8.2f}\n",
cvar, ulvar, bvar, fvar);
}
Mehrere Variablen desselben Datentyps können in einer Anweisung definiert werden, wobei die Variablennamen durch Komma getrennt werden.
short svar1, svar2; // Zwei short-Variablen
float fvar1, fvar2; // und zwei float-Variablen
Variablen können bei ihrer Definition mit einem Datum initialisiert werden. Dies erfolgt in der Art, dass nach dem Variablenname der Zuweisungsoperator = folgt und anschließend der Initialwert.
short svar1=1, svar2=10; // Zwei short-Variablen
float fvar1=1.2f, fvar2=3.14f; // und zwei float-Variablen initialisieren
Konstanten sind Daten, die nach ihrer Definition nicht mehr geändert werden können.
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, aber mindestens den Datentyp int. Um ein Ganzzahl-Literal explizit einem Datentyp zuzuordnen, wird der Wert mit einem Präfix oder Suffix erweitert. Die Groß-/Kleinschreibung spielt hier ausnahmsweise keine Rolle
Gleitkomma-Literale bestehen aus Ziffern und einem Dezimalpunkt. Optional kann ein Gleitkomma-Literal einen Exponenten enthalten. Standardmäßig sind Gleitkomma-Literale vom Datentyp double.
Um einem Gleitkomma-Literal einen von double abweichenden Datentyp zuzuweisen, wird das Literal mit einem Suffix laut nachfolgender Tabelle erweitert. Auch hier spielt die Groß-/Kleinschreibung keine Rolle
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 haben den Datentyp const char[n] (char-Feld mit n konstanten Zeichen). Das letzte Zeichen eines String-Literals ist immer eine abschließende 0 (Null).
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. Benannte Konstanten müssen bei ihrer Definition initialisiert werden.
const int SIZE=10; // int-Konstante
const double PI=3.1416; // double-Konstante
Der Spezifizierer constexpr weist den Compiler an, den Initialisierungsausdruck zum Zeitpunkt des Übersetzungsvorgangs auszuwerten. Kann der Ausdruck während des Übersetzungsvorgangs nicht berechnet werden, erzeugt dies einen Fehler.
int main()
{
int anyVar = 10; // Variable def./init.
const int anyConst = anyVar; // Konstante definieren
constexpr int anyCExpr1 = 10; // Ok
constexpr int anyCExpr2 = anyVar; // Fehler! anyVar ist kein konstanter Ausdruck
}
Werden Daten bei ihrer Definition initialisiert, kann der Compiler aufgrund des Datentyps des Initialisierungsausdrucks den Datentyp der Variable bestimmen. Hierzu wird der explizite Datentyp bei der Definition des Datums durch das Schlüsselwort auto ersetzt.
Das obige Beispiel mit auto-Variablen sieht dann wie folgt aus:
// Header-Datei einbinden
#include <iostream>
#include <format>
// Definition einer char Variable und unsigned long Konstante
auto cvar = 'A';
const auto ulvar= 1'000'000UL;
int main()
{
// Definition einer bool Variable und float Konstante
auto bvar = false;
const auto fvar = 1.8888f;
// Ausgabe der Daten
std::cout << std::format("char: {:x}, unsigned long: {}\n"
"bool: {}, float: {:8.2f}\n",
cvar, ulvar, bvar, fvar);
}
char: 41, unsigned long: 1000000
bool: false, float: 1.89
Referenz-Variablen enthalten Verweise auf bereits definierte Daten. Um eine Referenz-Variable zu definieren, folgt nach dem Datentyp das Symbol &, dann der Name der Referenz-Variable und anschließend der Zuweisungsoperator sowie der Name des Datums, auf die die Referenz verweisen soll.
int iVar; // int-Variable definieren
int& refVar = iVar; // Referenz-Variable definieren, verweist auf iVar
Referenz-Variablen unterliegen folgenden Einschränkungen:
Vielleicht mag im Augenblick die Verwendung von Referenz-Variablen noch etwas merkwürdig erscheinen. Später aber werden Sie den Einsatz von Referenzen noch zu schätzen wissen.
Mit Hilfe des Spezifizierers decltype() kann der Datentyp eines Ausdrucks bestimmt und damit unter anderem der Datentyp eines Datums indirekt festlegt werden. Die allgemeine Syntax lautet:
decltype (AUSDRUCK)
Wird für AUSDRUCK ein Datum eingesetzt, liefert decltype() den Datentyp des Datums zurück. Wird für AUSDRUCK ein Funktionsaufruf eingesetzt, liefert decltype() den Returntyp der Funktion. Es gibt für AUSDRUCK noch weitere Möglichkeiten, auf die in dieser Einführung aber nicht weiter eingegangen werden soll.
// Header-Datei einbinden
#include <iostream>
#include <format>
int main()
{
// float-Variable definieren
float var1;
// Variable mit demselben Datentyp wie var1 definieren
decltype(var1) var2;
// Variable definieren, die einen von main()
// zurueckgegebenen Wert aufnehmen koennte
decltype(main()) retVal;
// Datentyp der Variablen ausgeben
// Der verwendete Operator typeid wird spaeter noch behandelt
// In diesem Beispiel gibt typeid(x).name() den Namen des
// Datentyps x aus.
std::cout << std::format("Datentyp var1: {}, Datentyp var2: {}\n",
typeid(var1).name(), typeid(var2).name());
std::cout << std::format("Returntyp main(): {}, Datentyp retVal: {}\n",
typeid(int).name(),typeid(retVal).name());
}
Um die von einem Datentyp oder Datum benötigte Anzahl von Bytes zu bestimmen, wird der sizeof-Operator verwendet.
auto intBytes = sizeof(int);
short sVar;
auto shortBytes = sizeof(sVar);
Damit wollen wir die Behandlung von Daten abschließen und wenden uns den Operatoren zu.