Le type d'une variable indique au compilateur ce que cette variable est supposée représenter. Une variable peut contenir un entier, une valeur réelle, un caractère, l'adresse d'une autre variable... la liste est longue. Il est donc important que le compilateur sache quel type de variable il doit attendre. Plus encore, étant donné que les différents types de variables peuvent avoir des tailles en mémoire différentes, le compilateur a besoin de savoir absolument quelle quantité de mémoire il doit allouer.
La syntaxe pour déclarer une variable en précisant son type est :
type nomDeVariable;
Voici ici listés les différents types fondamentaux du C++ :
Les types fondamentaux
Le type int est le type le plus "classique" : il représente les valeurs entières. C'est aussi le type le plus apprécié par le processeur, car c'est le seul qu'il est réellement capable de manipuler naturellement : c'est donc le type qui permet de faire les calculs les plus rapides. Mais cette vitesse à un coût : il ne s'agit que de nombres entiers, alors que la plupart des applications calculatoires nécessitent des valeurs réelles, plus précises.
La taille allouée à une variable de type int dépend de l'architecture. Aujourd'hui (en l'an 2000, si c'est pas malheureux!!!), les processeurs "classiques", entendez par là "commerciaux", sont basés sur une architecture 32 bits, ce qui fait que les int sont codés sur 32 bits. Attention, sur une architecture 16 bits (de moins en moins courantes aujourd'hui), les int sont codés sur 16 bits, et peuvent alors prendre les mêmes valeurs que les short. Sur 32 bits, on peut représenter 4 294 967 266 valeurs différentes avec un int. Si le int est déclaré signed, il peut prendre des valeurs allant de -2 147 483 648 à 2 147 483 647 (encore une fois, ceci dépend de l'architecture), alors qu'en unsigned, il s'étend de 0 à 4 294 967 265.
Les expressions littérales du type 5, 145 ou -1434 sont par défaut des valeurs int.
Les trois types entiers int, short et long ont un comportement étrange lorsqu'on leur assigne une valeur qui dépasse leur capacité : si la valeur est trop grande, au lieu de continuer à monter, elle revient à la valeur la plus basse possible. Ainsi, si vous donnez à un int la valeur 4 294 967 265, et qu'après vous l'incrémentez, vous vous retrouvez à 0!!!
Le type short existe pour donner une alternative au type int : il est plus court (en théorie). Ceci fait qu'il prend moins de place en mémoire, mais ne peut que recevoir des valeurs plus petites. Si je vous dis en théorie, c'est parce qu'il n'y a pas de garantie que le short soit réellement plus petit que le int : cela dépend de l'implémentation utilisée. Cependant, il est très très courant que les short soient codés sur 16 bits, quelque soit l'architecture. Il peut donc prendre des valeurs allant de 0 à 65 535 en unsigned, et de -32 763 à 32 762 en signed.
Sur une valeur littérale entière est assignée à un short, le compilateur regarde si cette valeur est bien dans les limites du short, auquel cas il convertit cette valeur en short et l'assigne à la variable de type short, en la rendant unsigned si cela est nécessaire pour y faire tenir la valeur indiquée. Si la valeur est trop grande, il y a ce phénomène de rotation de la valeur décrit pour les int.
Le long offre encore une altérnative au int, mais vers le haut cette fois-ci. Encore une fois, il n'est pas garanti que le long soit plus grand que le int, mais il est très commun qu'il soit codé sur 32 bits, quelque soit l'architecture. Sur une architecture 32 bits, il prend donc les mêmes valeurs que le int 32 bit.
Après les entiers, on en vient aux réels. Le type de base des réels est le float, couramment codé sur 32 bits. Ses valeurs s'étendent de 3.4E-38 à 3.4E+38, avec une précision de 7 chiffres.
Les expressions littérales réelles sont par défaut du type float. Si une valeur trop grande est assignée à un type réel, il vaudra la valeur infinie.
Le double offre plus de précision que le float, étant codé sur 64 bits. Il peut aller de 1.7E-308 à 1.7E+308, avec une précision de 15 chiffres.
Le long double est codé sur 80 bits, offrant une plage de valeurs allant de 1.2E-4932 à 1.2E+4932, avec une précision de 19 chiffres.
Typiquement, les char servent à représenter des caractères. Codés sur 8 bits, ils offrent une plage de valeur allant de -128 à 127 en signed, ou de 0 à 255 en unsigned. Toutes les tailles des autres types sont des multiples de la taille du char.
Le type char est un peu différent, car son code ne dit pas ce qu'il représente : si une variable de type char est codée par le nombre 46, on ne sait pas à priori quel caractère elle représente. De plus, il faut faire attention au fait que le caractère '9' est différent de la valeur 9.
Le char n'est pas signed ou unsigned par défaut. Le unsigned char peut servir à représenter un octet, c'est-à-dire l'équivalent dy type byte qu'on retrouve dans d'autres langages. Ce type peut être très pratique pour faire un champ de bits (où chaque bit représente une valeur de vérité. On regarde donc plutôt les bits individuellement que dans leur ensemble).
La spécification signed ou unsigned ne s'applique qu'aux types entiers et au type char. Elle permet de préciser si on veut que la variable ainsi déclarée soit signée (et donc qu'elle puisse prendre des valeurs négatives) ou non.
Un seul de ces deux spécificateurs peut être utilisé en même temps. Si il est présent dans la déclaration d'une variable de type int, on peut se passer de "int", il est assumé :
unsigned int x = 10; équivaut à unsigned x = 10;
Par défaut, les entiers sont signed.
L'opérateur sizeof
Le C++ possède un opérateur sizeof, qui vous permet de savoir, lors de l'exécution, le nombre d'octets qu'une variable prend en mémoire. Ainsi, vous pourrez par vous même vérifier les valeurs que je vous ai donné ici. Voici un petit exemple :
int x = 0;
double y = 0; cout << sizeof(x) << " - " << sizeof(y) << endl; |
sizeof vous donne la taille en octets : multipliez par 8 pour obtenir la taille en bits.