C++ Types de données
Lorsque l'on programme dans un langage de programmation, diverses variables sont nécessaires pour stocker divers types d'informations. Une variable conserve l'emplacement mémoire de la valeur qu'elle stocke. Cela signifie que lorsque vous créez une variable, un certain espace est réservé en mémoire.
Vous pouvez avoir besoin de stocker des informations de divers types de données (tels que caractère, caractère large, entier, nombre à virgule flottante, nombre à virgule flottante double, booléen, etc.). Le système d'exploitation allouera de la mémoire en fonction du type de données de la variable et décidera de ce qu'il faut stocker dans la mémoire réservée.
Types de base intégrés
C++ fournit aux programmeurs une riche variété de types de données intégrés et de types de données définis par l'utilisateur. Le tableau suivant répertorie sept types de données C++ de base :
| Type | Mots-clés |
|---|---|
| Type booléen | bool |
| Type caractère | char |
| entier | int |
| Type à virgule flottante | float |
| Type à virgule flottante double | double |
| Void | void |
| Type caractère large | wchar_t |
En fait, wchar_t est dérivé comme ceci :
typedef short int wchar_t;
Par conséquent, wchar_t occupe en fait le même espace que short int.
Certains types de base peuvent être modifiés avec un ou plusieurs modificateurs de type :
| Modificateurs | Description | Exemple |
|---|---|---|
signed | Indique un type signé (par défaut) | signed int x = -10; |
unsigned | Désigne un type non signé | unsigned int y = 10; |
short | Désigne un type entier court | short int z = 100; |
long | Désigne un type entier long | long int a = 100000; |
const | Indique une constante, la valeur ne peut pas être modifiée | const int b = 5; |
volatile | Indique que la variable peut être modifiée de manière inattendue, ce qui empêche l'optimisation du compilateur. | volatile int c = 10; |
mutable | Indique que les membres d'une classe peuvent êtreconstModifiés dans l'objet | mutable int counter; |
Le tableau suivant montre la mémoire requise pour divers types de variables lors du stockage de valeurs en mémoire, ainsi que les valeurs maximale et minimale qu'une variable de ce type peut stocker.
Remarque :Il peut y avoir des différences entre les différents systèmes ; un octet correspond à 8 bits.
Remarque :Par défaut, int, short et long sont signés.
Remarque :long int occupe 8 octets, et int occupe toujours 4 octets. Les premiers compilateurs C définissaient long int comme occupant 4 octets et int comme occupant 2 octets. Les normes C/C++ plus récentes sont compatibles avec ce paramètre d'origine.
| Types de données | Description | Taille (octets) | Exemple de plage/valeur |
|---|---|---|---|
bool | Type booléen, représentant true ou false | 1 | trueoufalse |
char | Type caractère, généralement utilisé pour stocker des caractères ASCII. | 1 | -128 à 127 ou 0 à 255 |
signed char | Type caractère signé | 1 | -128 à 127 |
unsigned char | Type de caractère non signé | 1 | 0 à 255 |
wchar_t | Type de caractère large, utilisé pour stocker des caractères Unicode. | 2 ou 4 | Dépend de la plateforme |
char16_t | Type de caractère Unicode 16 bits (introduit en C++11) | 2 | 0 à 65,535 |
char32_t | Type de caractère Unicode 32 bits (introduit en C++11) | 4 | 0 à 4,294,967,295 |
short | entier court | 2 | -32,768 à 32,767 |
unsigned short | Entier court non signé | 2 | 0 à 65,535 |
int | entier | 4 | -2,147,483,648 à 2,147,483,647 |
unsigned int | Type entier non signé | 4 | 0 à 4,294,967,295 |
long | entier long | 4 ou 8 | Dépend de la plateforme |
unsigned long | Entier long non signé | 4 ou 8 | Dépend de la plateforme |
long long | Entier long long (introduit en C++11) | 8 | -9,223,372,036,854,775,808 à 9,223,372,036,854,775,807 |
unsigned long long | Entier long long non signé (introduit en C++11) | 8 | 0 à 18,446,744,073,709,551,615 |
float | Virgule flottante simple précision | 4 | Environ ±3.4e±38 (6-7 chiffres significatifs) |
double | Virgule flottante en double précision | 8 | Environ ±1.7e±308 (15 chiffres significatifs) |
long double | Virgule flottante en précision étendue | 8, 12 ou 16 | Dépend de la plateforme |
Nouveaux types ajoutés en C++11
| Types de données | Description | Exemple |
|---|---|---|
auto | Déduction automatique de type | auto x = 10; |
decltype | Obtenir le type d'une expression | decltype(x) y = 20; |
nullptr | Constante de pointeur nul | int* ptr = nullptr; |
std::initializer_list | Type de liste d'initialisation | std::initializer_list<int> list = {1, 2, 3}; |
std::tuple | Type tuple, qui peut stocker plusieurs valeurs de types différents. | std::tuple<int, float, char> t(1, 2.0, 'a'); |
Notez que la taille de stockage des différents types est liée à la largeur de bits du système, mais actuellement, le courant dominant est principalement constitué de systèmes 64 bits.
Ce qui suit présente les différences de taille de stockage entre les systèmes 32 bits et les systèmes 64 bits (Windows est identique) :
D'après le tableau ci-dessus, on peut voir que la taille des variables variera en fonction du compilateur et de l'ordinateur utilisés.
L'exemple suivant affichera la taille de divers types de données sur votre ordinateur.
Exemple
Cet exemple utiliseendl, ceci insérera un caractère de nouvelle ligne après chaque ligne,<<Les opérateurs sont utilisés pour transmettre plusieurs valeurs à l'écran,sizeof()L'opérateur est utilisé pour obtenir la taille de divers types de données.
Lorsque le code ci-dessus est compilé et exécuté, il produira les résultats suivants, qui peuvent varier selon l'ordinateur utilisé :
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**************
Types de données dérivés
| Types de données | Description | Exemple |
|---|---|---|
Array | Une collection d'éléments du même type | int arr[5] = {1, 2, 3, 4, 5}; |
Pointer | Un type qui stocke l'adresse mémoire d'une variable | int* ptr = &x; |
Reference | Alias de variable | int& ref = x; |
Function | Type de fonction, représentant la signature d'une fonction | int func(int a, int b); |
Struct | Type de données défini par l'utilisateur, pouvant contenir plusieurs membres de types différents. | struct Point { int x; int y; }; |
Class | Type de données défini par l'utilisateur, prenant en charge l'encapsulation, l'héritage et le polymorphisme. | class MyClass { ... }; |
Union | Plusieurs membres partagent le même bloc de mémoire | union Data { int i; float f; }; |
Enum | Un ensemble de constantes entières défini par l'utilisateur | enum Color { RED, GREEN, BLUE }; |
Alias de type
| Alias | Description | Exemple |
|---|---|---|
typedef | Définir un alias pour un type existant | typedef int MyInt; |
using | Définir un alias pour un type existant (introduit en C++11) | using MyInt = int; |
Type de la bibliothèque standard
| Types de données | Description | Exemple |
|---|---|---|
std::string | Type de chaîne | std::string s = "Hello"; |
std::vector | Tableau dynamique | std::vector<int> v = {1, 2, 3}; |
std::array | Tableau de taille fixe (introduit en C++11) | std::array<int, 3> a = {1, 2, 3}; |
std::pair | Un conteneur qui stocke deux valeurs | std::pair<int, float> p(1, 2.0); |
std::map | Conteneur de paires clé-valeur | std::map<int, std::string> m; |
std::set | Ensemble de valeurs uniques | std::set<int> s = {1, 2, 3}; |
Déclaration typedef
Vous pouvez utilisertypedefpour donner un nouveau nom à un type existant. Voici la syntaxe pour définir un nouveau type à l'aide de typedef :
typedef type newname;
Par exemple, l'instruction suivante indique au compilateur que feet est un autre nom pour int :
typedef int feet;
Maintenant, la déclaration suivante est parfaitement légale ; elle crée une variable entière distance :
feet distance;
Type énuméré
Le type énuméré (énumération) est un type de données dérivé en C++, qui est une collection de plusieurs constantes d'énumération définies par l'utilisateur.
Si une variable n'a que quelques valeurs possibles, elle peut être définie comme un type énuméré. L'« énumération » consiste à lister les valeurs de la variable une par une, et la valeur de la variable ne peut se situer que dans la plage des valeurs listées.
Pour créer une énumération, vous devez utiliser le mot-cléenum. La forme générale d'un type énuméré est :
enum 枚举名{
标识符[=整型常数],
标识符[=整型常数],
...
标识符[=整型常数]
} 枚举变量;
Si l'énumération n'est pas initialisée, c'est-à-dire lorsque "= integer constant" est omis, elle commence à partir du premier identifiant.
Par exemple, le code suivant définit une énumération color, et le type de la variable c est color. Enfin, c se voit attribuer la valeur "blue".
enum color { red, green, blue } c;
c = blue;
Par défaut, la valeur du premier nom est 0, la valeur du deuxième nom est 1, la valeur du troisième nom est 2, et ainsi de suite. Cependant, vous pouvez également attribuer une valeur spéciale à un nom en ajoutant simplement une valeur initiale. Par exemple, dans l'énumération suivante,greenLa valeur est 5.
enum color { red, green=5, blue };
Ici,bluea une valeur de 6, car par défaut, chaque nom est supérieur de 1 au nom précédent, mais la valeur de red est toujours 0.
Conversion de type
La conversion de type est la conversion d'une valeur d'un type de données en une valeur d'un autre type de données.
Il existe quatre types de conversion de type en C++ : la conversion statique, la conversion dynamique, la conversion const et la conversion reinterpret.
Conversion statique
La conversion statique est la conversion forcée d'une valeur d'un type de données en une valeur d'un autre type de données.
La conversion statique est généralement utilisée pour les conversions entre objets de types similaires, par exemple, convertir un type int en un type float.
La conversion statique n'effectue aucune vérification de type à l'exécution, elle peut donc entraîner des erreurs d'exécution.
Exemple
Cast dynamique
La conversion dynamique (dynamic_cast) est un mécanisme en C++ utilisé pour le downcasting dans une hiérarchie d'héritage.
La conversion dynamique est généralement utilisée pour convertir un pointeur ou une référence de classe de base en pointeur ou référence de classe dérivée.
Le cast dynamique effectue une vérification de type à l'exécution. Si la conversion échoue, il renvoie nullptr pour les types pointeur, et lance une exception std::bad_cast pour les types référence.
Syntaxe :
dynamic_cast<目标类型>(表达式)
Type cible: doit être un type pointeur ou référence.
Expression: le pointeur ou la référence de classe de base à convertir.
Exemple : cast dynamique de types pointeur
Sortie :
Derived class method
Exemple : transtypage dynamique de types de référence
#include <typeinfo>
class Base {
public:
virtual ~Base() = default; // La classe de base doit avoir des fonctions virtuelles
};
class Derived : public Base {
public:
void show() {
std::cout << "Méthode de la classe dérivée" << std::endl;
}
};
int main() {
Derived derived_obj;
Base& ref_base = derived_obj; // Référence de classe de base liée à un objet de classe dérivée
try {
// Convertir une référence de classe de base en référence de classe dérivée
Derived& ref_derived = dynamic_cast<Derived&>(ref_base);
ref_derived.show(); // Conversion réussie, appeler la méthode de la classe dérivée
} catch (const std::bad_cast& e) {
std::cout << "Échec du cast dynamique : " << e.what() << std::endl;
}
return 0;
}
Sortie :
Derived class method
| Fonctionnalités | Type de pointeur | Type de référence |
|---|---|---|
| Valeur de retour en cas d'échec de conversion | returnnullptr | Lancerstd::bad_castException |
| Scénarios applicables | Conversion descendante, vérification de type à l'exécution | Conversion descendante, vérification de type à l'exécution |
| Surcoût de performance | Plus élevé | Plus élevé |
| Exigence de classe de base | Doit avoir des fonctions virtuelles | Doit avoir des fonctions virtuelles |
Conversion const
La conversion const est utilisée pour convertir un objet de type const en un objet de type non const.
La conversion const peut être utilisée pour supprimer le const ; elle ne peut pas modifier le type de l'objet.
Exemple
Conversion de réinterprétation
La conversion de réinterprétation réinterprète une valeur d'un type de données comme une valeur d'un autre type de données, généralement pour des conversions entre différents types de données.
La conversion de réinterprétation n'effectue aucune vérification, ce qui peut entraîner un comportement indéfini.
