1.5 Les types prédéfinisLe C est un langage
typé.
Cela signifie en particulier que toute variable, constante ou fonction est d'un
type précis. Le type d'un objet définit la façon dont il est représenté en
mémoire.
La mémoire de l'ordinateur se
décompose en une suite continue d'octets. Chaque octet de la mémoire est
caractérisé par son
adresse, qui est un entier. Deux octets contigus
en mémoire ont des adresses qui diffèrent d'une unité. Quand une variable est
définie, il lui est attribué une adresse. Cette variable correspondra à une
zone mémoire dont la longueur (le nombre d'octets) est fixée par le type.
La taille mémoire correspondant
aux différents types dépend des compilateurs ; toutefois, la norme ANSI
spécifie un certain nombre de contraintes.
Les types de base en C
concernent les caractères, les entiers et les flottants (nombres réels). Ils
sont désignés par les mots-clefs suivants :
char
|
|
int
|
|
float
| double
|
short
| long
| Unsigned
|
1.5.1 Le type caractèreLe mot-clef char désigne
un objet de type caractère. Un char
peut contenir n'importe quel élément du jeu de caractères de la machine
utilisée. La plupart du temps, un objet de type char est codé sur un octet ; c'est l'objet le plus
élémentaire en C. Le jeu de caractères utilisé correspond généralement au
codage ASCII (sur 7 bits). La plupart des machines utilisent désormais le
jeu de caractères ISO-8859 (sur 8 bits), dont les 128 premiers caractères
correspondent aux caractères ASCII. Les 128 derniers caractères (codés sur
8 bits) sont utilisés pour les caractères propres aux différentes langues.
Une des particularités du type char en C est qu'il peut être assimilé
à un entier : tout objet de type char
peut être utilisé dans une expression qui utilise des objets de type entier.
Par exemple, si c est de type char, l'expression c + 1 est valide. Elle désigne le
caractère suivant dans le code ASCII. La table précédente donne le code ASCII
(en décimal, en octal et en hexadécimal) des caractères imprimables. Ainsi, le
programme suivant imprime le caractère 'B'.
main(){ char c = 'A'; printf("%c", c + 1);}
Suivant les implémentations, le type char est signé ou non. En cas de doute, il
vaut mieux préciser unsigned char
ou signed char. Notons que tous
les caractères imprimables sont positifs.
1.5.2 Les types entiersLe mot-clef désignant le type
entier est int. Un objet de type
int est représenté par un mot
``naturel'' de la machine utilisée, 32 bits pour un DEC alpha ou un PC
Intel.
Le type int peut être précédé
d'un attribut de précision (short
ou long) et/ou d'un attribut de
représentation (unsigned).Un
objet de type short int a au
moins la taille d'un char et au
plus la taille d'un int. En
général, un short int est codé
sur 16 bits. Un objet de type long int
a au moins la taille d'un int
(64 bits sur un DEC alpha, 32 bits sur un PC Intel).
| DEC Alpha
| PC Intel (Linux)
|
|
char
| 8 bits
| 8 bits
| caractère
|
short
| 16 bits
| 16 bits
| entier court
|
int
| 32 bits
| 32 bits
| entier
|
long
| 64 bits
| 32 bits
| entier long
|
long long
| n.i.
| 64 bits
| entier long (non ANSI)
|
Table 1.2: Les types entiers
Le bit de poids fort d'un
entier est son signe. Un entier positif est donc représenté en mémoire par la
suite de 32 bits dont le bit de poids fort vaut 0 et les 31 autres bits
correspondent à la décomposition de l'entier en base 2. Par exemple, pour
des objets de type char (8
bits), l'entier positif 12 sera représenté en mémoire par 00001100. Un entier
négatif est, lui, représenté par une suite de 32 bits dont le bit de poids
fort vaut 1 et les 31 autres bits correspondent à la valeur absolue
de l'entier représentée suivant la technique dite du ``complément à 2''. Cela
signifie que l'on exprime la valeur absolue de l'entier sous forme binaire, que
l'on prend le complémentaire bit-à-bit de cette valeur et que l'on
ajoute 1 au résultat. Ainsi, pour des objets de type signed char (8 bits), -1 sera
représenté par 11111111, -2 par 11111110, -12 par par 11110100.Un int peut donc représenter un entier entre
-2
31 et (2
31-1). L'attribut unsigned spécifie que l'entier n'a pas de
signe. Un unsigned int peut donc
représenter un entier entre 0 et (2
32-1).
Sur un DEC alpha, on utilisera donc un des types suivants en fonction de la
taille des données à stocker :
signed char
| [-27;27[
|
unsigned char
| [0;28[
|
short int
| [-215; 215[
|
unsigned short int
| [0;216[
|
Int
| [-231;231[
|
unsigned int
| [0;232[
|
long int (DEC alpha)
| [-263;263[
|
unsigned long int (DEC alpha)
| [0;264[
|
Le mot-clef sizeof(expression) où unsigned short x;
taille = sizeof(x);
Dans les deux cas, limits.h ou le
résultat obtenu en appliquant l'opérateur