C++ Datentypen
Bei der Programmierung in einer Programmiersprache werden verschiedene Variablen benötigt, um verschiedenartige Informationen zu speichern. Eine Variable behält den Speicherort des von ihr gespeicherten Werts. Das bedeutet, dass beim Erstellen einer Variablen Speicherplatz im Arbeitsspeicher reserviert wird.
Sie müssen möglicherweise Informationen verschiedener Datentypen speichern (z. B. Zeichen, Breitzeichen, Ganzzahl, Gleitkommazahl, doppelte Gleitkommazahl, Boolean usw.). Das Betriebssystem reserviert Speicher auf Grundlage des Datentyps der Variable und entscheidet, was im reservierten Speicher abgelegt wird.
Grundlegende integrierte Typen
C++ bietet Programmierern eine große Vielfalt an integrierten Datentypen und benutzerdefinierten Datentypen. Die folgende Tabelle listet sieben grundlegende C++-Datentypen auf:
| Type | Schlüsselwörter |
|---|---|
| Boolescher Typ | bool |
| Zeichentyp | char |
| integer | int |
| Gleitkommatyp | float |
| Double-Gleitkommatyp | double |
| Void | void |
| Breitzeichen-Typ | wchar_t |
Tatsächlich wird wchar_t wie folgt abgeleitet:
typedef short int wchar_t;
Daher belegt wchar_t tatsächlich denselben Speicherplatz wie short int.
Einige grundlegende Typen können mit einem oder mehreren Typmodifikatoren geändert werden:
| Modifizierer | Beschreibung | Beispiel |
|---|---|---|
signed | Bezeichnet einen vorzeichenbehafteten Typ (Standard) | signed int x = -10; |
unsigned | Bezeichnet einen vorzeichenlosen Typ | unsigned int y = 10; |
short | Bezeichnet einen kurzen Ganzzahltyp | short int z = 100; |
long | Bezeichnet einen langen Ganzzahltyp | long int a = 100000; |
const | Bezeichnet eine Konstante, der Wert kann nicht geändert werden | const int b = 5; |
volatile | Gibt an, dass die Variable unerwartet geändert werden kann, und verbietet Compiler-Optimierung. | volatile int c = 10; |
mutable | Gibt an, dass Klassenmitgliederconstim Objekt geändert werden können | mutable int counter; |
Die folgende Tabelle zeigt den Speicherbedarf verschiedener Variablentypen beim Speichern von Werten im Speicher sowie die maximalen und minimalen Werte, die eine Variable dieses Typs speichern kann.
Hinweis:Es kann Unterschiede zwischen verschiedenen Systemen geben; ein Byte ist 8 Bits.
Hinweis:Standardmäßig sind int, short und long vorzeichenbehaftet.
Hinweis:long int ist 8 Bytes und int ist immer 4 Bytes. Frühe C-Compiler legten fest, dass long int 4 Bytes und int 2 Bytes belegt. Die neueren C/C++-Standards sind mit dieser frühen Festlegung kompatibel.
| Datentypen | Beschreibung | Größe (Bytes) | Bereich/Wert-Beispiel |
|---|---|---|---|
bool | Boolescher Typ, der true oder false repräsentiert | 1 | trueoderfalse |
char | Zeichentyp, wird normalerweise zum Speichern von ASCII-Zeichen verwendet. | 1 | -128 bis 127 oder 0 bis 255 |
signed char | Vorzeichenbehafteter Zeichentyp | 1 | -128 bis 127 |
unsigned char | Vorzeichenloser Zeichentyp | 1 | 0 bis 255 |
wchar_t | Breitzeichen-Typ, wird zum Speichern von Unicode-Zeichen verwendet. | 2 oder 4 | Plattformabhängig |
char16_t | 16-Bit-Unicode-Zeichentyp (in C++11 eingeführt) | 2 | 0 bis 65,535 |
char32_t | 32-Bit-Unicode-Zeichentyp (in C++11 eingeführt) | 4 | 0 bis 4,294,967,295 |
short | Kurze Ganzzahl | 2 | -32,768 bis 32,767 |
unsigned short | Vorzeichenlose kurze Ganzzahl | 2 | 0 bis 65,535 |
int | integer | 4 | -2,147,483,648 bis 2,147,483,647 |
unsigned int | Vorzeichenloser Ganzzahltyp | 4 | 0 bis 4,294,967,295 |
long | Lange Ganzzahl | 4 oder 8 | Plattformabhängig |
unsigned long | Vorzeichenlose lange Ganzzahl | 4 oder 8 | Plattformabhängig |
long long | Lange lange Ganzzahl (in C++11 eingeführt) | 8 | -9,223,372,036,854,775,808 bis 9,223,372,036,854,775,807 |
unsigned long long | Vorzeichenlose lange lange Ganzzahl (in C++11 eingeführt) | 8 | 0 bis 18,446,744,073,709,551,615 |
float | Gleitkommazahl einfacher Genauigkeit | 4 | Ungefähr ±3.4e±38 (6-7 signifikante Stellen) |
double | Gleitkommazahl mit doppelter Genauigkeit | 8 | Ungefähr ±1.7e±308 (15 signifikante Stellen) |
long double | Gleitkommazahl mit erweiterter Genauigkeit | 8, 12 oder 16 | Plattformabhängig |
Neue Typen, die in C++11 hinzugefügt wurden
| Datentypen | Beschreibung | Beispiel |
|---|---|---|
auto | Automatische Typableitung | auto x = 10; |
decltype | Den Typ eines Ausdrucks ermitteln | decltype(x) y = 20; |
nullptr | Nullzeigerkonstante | int* ptr = nullptr; |
std::initializer_list | Initialisierungslistentyp | std::initializer_list<int> list = {1, 2, 3}; |
std::tuple | Tupeltyp, der mehrere Werte unterschiedlicher Typen speichern kann. | std::tuple<int, float, char> t(1, 2.0, 'a'); |
Beachten Sie, dass die Speichergröße verschiedener Typen von der Systembitbreite abhängt, aber derzeit hauptsächlich 64-Bit-Systeme vorherrschen.
Im Folgenden sind die Unterschiede in der Speichergröße zwischen 32-Bit-Systemen und 64-Bit-Systemen aufgeführt (für Windows gilt dasselbe):
Aus der obigen Tabelle ist ersichtlich, dass die Größe von Variablen je nach Compiler und verwendetem Computer variiert.
Das folgende Beispiel gibt die Größe verschiedener Datentypen auf Ihrem Computer aus.
Beispiel
Dieses Beispiel verwendetendl, dabei wird nach jeder Zeile ein Zeilenumbruchzeichen eingefügt,<<Operatoren werden verwendet, um mehrere Werte an den Bildschirm auszugeben,sizeof()Der Operator wird verwendet, um die Größe verschiedener Datentypen zu ermitteln.
Wenn der obige Code kompiliert und ausgeführt wird, erzeugt er die folgenden Ergebnisse, die je nach verwendetem Computer variieren können:
type: ************size************** bool: 所占字节数:1 最大值:1 最小值:0 char: 所占字节数:1 最大值: 最小值:? signed char: 所占字节数:1 最大值: 最小值:? unsigned char: 所占字节数:1 最大值:? 最小值: wchar_t: 所占字节数:4 最大值:2147483647 最小值:-2147483648 short: 所占字节数:2 最大值:32767 最小值:-32768 int: 所占字节数:4 最大值:2147483647 最小值:-2147483648 unsigned: 所占字节数:4 最大值:4294967295 最小值:0 long: 所占字节数:8 最大值:9223372036854775807 最小值:-9223372036854775808 unsigned long: 所占字节数:8 最大值:18446744073709551615 最小值:0 double: 所占字节数:8 最大值:1.79769e+308 最小值:2.22507e-308 long double: 所占字节数:16 最大值:1.18973e+4932 最小值:3.3621e-4932 float: 所占字节数:4 最大值:3.40282e+38 最小值:1.17549e-38 size_t: 所占字节数:8 最大值:18446744073709551615 最小值:0 string: 所占字节数:24 type: ************size**************
Abgeleitete Datentypen
| Datentypen | Beschreibung | Beispiel |
|---|---|---|
Array | Eine Sammlung von Elementen desselben Typs | int arr[5] = {1, 2, 3, 4, 5}; |
Pointer | Ein Typ, der die Speicheradresse einer Variablen speichert | int* ptr = &x; |
Reference | Variablen-Alias | int& ref = x; |
Function | Funktionstyp, der die Signatur einer Funktion darstellt | int func(int a, int b); |
Struct | Benutzerdefinierter Datentyp, der mehrere Member unterschiedlicher Typen enthalten kann. | struct Point { int x; int y; }; |
Class | Benutzerdefinierter Datentyp, der Kapselung, Vererbung und Polymorphie unterstützt. | class MyClass { ... }; |
Union | Mehrere Member teilen sich denselben Speicherblock | union Data { int i; float f; }; |
Enum | Ein benutzerdefinierter Satz von Integer-Konstanten | enum Color { RED, GREEN, BLUE }; |
Typalias
| Alias | Beschreibung | Beispiel |
|---|---|---|
typedef | Alias für einen vorhandenen Typ definieren | typedef int MyInt; |
using | Alias für einen vorhandenen Typ definieren (in C++11 eingeführt) | using MyInt = int; |
Standardbibliothekstyp
| Datentypen | Beschreibung | Beispiel |
|---|---|---|
std::string | String-Typ | std::string s = "Hello"; |
std::vector | Dynamisches Array | std::vector<int> v = {1, 2, 3}; |
std::array | Array mit fester Größe (in C++11 eingeführt) | std::array<int, 3> a = {1, 2, 3}; |
std::pair | Ein Container, der zwei Werte speichert | std::pair<int, float> p(1, 2.0); |
std::map | Container für Schlüssel-Wert-Paare | std::map<int, std::string> m; |
std::set | Menge eindeutiger Werte | std::set<int> s = {1, 2, 3}; |
typedef-Deklaration
Sie könnentypedefverwenden, um einem vorhandenen Typ einen neuen Namen zu geben. Das Folgende ist die Syntax zum Definieren eines neuen Typs mit typedef:
typedef type newname;
Zum Beispiel teilt die folgende Anweisung dem Compiler mit, dass feet ein anderer Name für int ist:
typedef int feet;
Nun ist die folgende Deklaration vollkommen zulässig; sie erzeugt eine Ganzzahlvariable distance:
feet distance;
Aufzählungstyp
Der Aufzählungstyp (Enumeration) ist ein abgeleiteter Datentyp in C++, der eine Sammlung mehrerer vom Benutzer definierter Aufzählungskonstanten ist.
Wenn eine Variable nur wenige mögliche Werte hat, kann sie als Aufzählungstyp definiert werden. Die sogenannte "Aufzählung" bedeutet, die Werte der Variablen einzeln aufzulisten, und der Wert der Variablen kann nur innerhalb des Bereichs der aufgelisteten Werte liegen.
Um ein enum zu erstellen, müssen Sie das Schlüsselwortenumverwenden. Die allgemeine Form eines enum-Typs ist:
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
} 枚举变量;
Wenn die Enumeration nicht initialisiert wird, d. h., wenn "= integer constant" weggelassen wird, beginnt sie beim ersten Bezeichner.
Zum Beispiel definiert der folgende Code eine Enumeration namens color, und der Typ der Variablen c ist color. Schließlich wird c der Wert "blue" zugewiesen.
enum color { red, green, blue } c;
c = blue;
Standardmäßig ist der Wert des ersten Namens 0, der Wert des zweiten Namens 1, der Wert des dritten Namens 2 und so weiter. Sie können einem Namen jedoch auch einen speziellen Wert zuweisen, indem Sie einfach einen Anfangswert hinzufügen. Zum Beispiel in der folgenden Enumeration,greenDer Wert ist 5.
enum color { red, green=5, blue };
Hier,bluehat einen Wert von 6, weil standardmäßig jeder Name um 1 größer ist als der Name davor, aber der Wert von red ist immer noch 0.
Typumwandlung
Typumwandlung ist die Umwandlung eines Werts eines Datentyps in einen Wert eines anderen Datentyps.
In C++ gibt es vier Arten der Typumwandlung: statische Umwandlung, dynamische Umwandlung, const-Umwandlung und reinterpret-Umwandlung.
Statischer Cast
Statische Umwandlung ist die erzwungene Umwandlung eines Werts eines Datentyps in einen Wert eines anderen Datentyps.
Statische Umwandlung wird normalerweise für Umwandlungen zwischen Objekten ähnlicher Typen verwendet, zum Beispiel die Umwandlung eines int-Typs in einen float-Typ.
Statischer Cast führt keine Laufzeit-Typprüfung durch, sodass er zu Laufzeitfehlern führen kann.
Beispiel
Dynamische Umwandlung
Dynamische Umwandlung (dynamic_cast) ist ein Mechanismus in C++, der für Downcasting in einer Vererbungshierarchie verwendet wird.
Dynamische Umwandlung wird normalerweise verwendet, um einen Zeiger oder Verweis auf eine Basisklasse in einen Zeiger oder Verweis auf eine abgeleitete Klasse umzuwandeln.
Dynamische Umwandlung führt zur Laufzeit eine Typprüfung durch. Wenn die Umwandlung fehlschlägt, gibt sie für Zeigertypen nullptr zurück und löst für Referenztypen eine std::bad_cast-Ausnahme aus.
Syntax:
dynamic_cast<目标类型>(表达式)
Zieltyp: Muss ein Zeiger- oder Referenztyp sein.
Ausdruck: Der Zeiger oder Verweis auf die Basisklasse, der umgewandelt werden muss.
Beispiel: Dynamische Umwandlung von Zeigertypen
Ausgabe:
Derived class method
Beispiel: Dynamischer Cast von Referenztypen
#include <typeinfo>
class Base {
public:
virtual ~Base() = default; // Die Basisklasse muss virtuelle Funktionen haben
};
class Derived : public Base {
public:
void show() {
std::cout << "Methode der abgeleiteten Klasse" << std::endl;
}
};
int main() {
Derived derived_obj;
Base& ref_base = derived_obj; // Basisklassenreferenz an Objekt der abgeleiteten Klasse gebunden
try {
// Basisklassenreferenz in Referenz der abgeleiteten Klasse umwandeln
Derived& ref_derived = dynamic_cast<Derived&>(ref_base);
ref_derived.show(); // Konvertierung erfolgreich, Methode der abgeleiteten Klasse aufrufen
} catch (const std::bad_cast& e) {
std::cout << "Dynamischer Cast fehlgeschlagen: " << e.what() << std::endl;
}
return 0;
}
Ausgabe:
Derived class method
| Funktionen | Zeigertyp | Referenztyp |
|---|---|---|
| Rückgabewert bei fehlgeschlagener Konvertierung | returnnullptr | Auslösenstd::bad_castAusnahme |
| Anwendbare Szenarien | Downcasting, Laufzeit-Typüberprüfung | Downcasting, Laufzeit-Typüberprüfung |
| Performance-Overhead | Höher | Höher |
| Anforderung an die Basisklasse | Muss virtuelle Funktionen haben | Muss virtuelle Funktionen haben |
Const-Cast
Die Const-Konvertierung wird verwendet, um ein Objekt vom Typ const in ein Objekt vom Typ non-const umzuwandeln.
Eine const-Konvertierung kann nur verwendet werden, um das const-Attribut zu entfernen; sie kann den Typ des Objekts nicht ändern.
Beispiel
Reinterpret-Cast
Die Reinterpret-Konvertierung interpretiert einen Wert eines Datentyps als Wert eines anderen Datentyps neu; sie wird normalerweise für Konvertierungen zwischen verschiedenen Datentypen verwendet.
Die Reinterpret-Konvertierung führt keine Typprüfung durch, was zu undefiniertem Verhalten führen kann.
