4.8. Arithmétique des pointeurs
Il est possible d'effectuer des opérations arithmétiques sur les pointeurs.
Les seules opérations valides sont les opérations externes (addition et
soustraction des entiers) et la soustraction de pointeurs. Elles sont définies comme suit (la soustraction
d'un entier est considérée comme l'addition d'un entier négatif) :
p + i = adresse contenue dans p + i*taille(élément pointé par p)
et :
p2 - p1 = (adresse contenue dans p2 - adresse contenue dans p1) /
taille(éléments pointés par p1 et p2)
Si p est un pointeur d'entier, p+1 est donc
le pointeur sur l'entier qui suit immédiatement celui pointé par p. On retiendra
surtout que l'entier qu'on additionne au pointeur est multiplié par la taille de l'élément pointé
pour obtenir la nouvelle adresse.
Le type du résultat de la soustraction de deux pointeurs est très dépendant
de la machine cible et du modèle mémoire du programme. En général, on ne pourra jamais supposer
que la soustraction de deux pointeurs est un entier (que les chevronnés du C me pardonnent, mais
c'est une erreur très grave). En effet, ce type peut être
insuffisant pour stocker des adresses (une machine peut avoir des adresses sur 64 bits et des données
sur 32 bits). Pour résoudre ce problème, le fichier d'en-tête
stdlib.h contient la définition du type à utiliser pour
la différence de deux pointeurs. Ce type est nommé ptrdiff_t.
Exemple 4-10. Arithmétique des pointeurs
int i, j;
ptrdiff_t delta = &i - &j; /* Correct */
int error = &i - &j; /* Peut marcher, mais par chance. */
Il est possible de connaître la taille d'un élément en caractères en utilisant
l'opérateur sizeof. Il a la syntaxe d'une fonction :
sizeof(type|expression)
Il attend soit un type, soit une expression. La valeur retournée est soit
la taille du type en caractères, soit celle du type de l'expression. Dans le cas des tableaux, il renvoie
la taille totale du tableau. Si son argument est une expression, celle-ci n'est pas évaluée (donc si
il contient un appel à une fonction, celle-ci n'est pas appelée). Par exemple :
renvoie la taille d'un entier en caractères, et :
renvoie la même taille, car
2+3 est de type entier.
2+3 n'est pas
calculé.
Note : L'opérateur sizeof renvoie la taille des types
en tenant compte de leur alignement. Cela signifie par exemple que même si un compilateur espace
les éléments d'un tableau afin de les aligner sur des mots mémoire de la machine, la taille des éléments
du tableau sera celle des objets de même type qui ne se trouvent pas dans ce tableau (ils devront
donc être alignés eux aussi). On a donc toujours l'égalité suivante :
sizeof(tableau) = sizeof(élément) * nombre d'éléments