© Éditions Eyrolles
135
chapitre n° 7
Les tableaux et les pointeurs
7.2 La soustraction de pointeurs
Là encore, quand deux pointeurs sont de même type, leur différence fournit le nombre d’éléments du type en question situés entre les deux adresses correspondantes. L’emploi de cette
possibilité est assez rare.
7.3 Les affectations de pointeurs et le pointeur nul
Nous avons naturellement déjà rencontré des cas d’affectation de la valeur d’un pointeur à un
pointeur de même type. A priori, c’est le seul cas autorisé par le langage C (du moins, tant que
l’on ne procède pas à des conversions explicites). Une exception a toutefois lieu en ce qui
concerne la valeur entière 0, ainsi que pour le type générique void * dont nous parlerons un
peu plus loin. Cette tolérance est motivée par le besoin de pouvoir représenter un pointeur nul,
c’est-à-dire ne pointant sur rien (c’est le nil du Pascal). Bien entendu, cela n’a d’intérêt que
parce qu’il est possible de comparer n’importe quel pointeur (de n’importe quel type) avec ce
« pointeur nul ».
D’une manière générale, plutôt que la valeur 0, il est conseillé d’employer la constante NULL
prédéfinie dans stdio.h, et également dans stddef.h (bien entendu, elle sera remplacée
par la constante entière 0 lors du traitement par le préprocesseur, mais les programmes source
en seront néanmoins plus lisibles).
Avec ces déclarations :
int * n ;
double * x ;
ces instructions seront correctes :
n = 0 ;
/* ou mieux */ n = NULL ;
x = 0 ;
/* ou mieux */ x = NULL ;
if (n == 0) ...
/* ou mieux */ if (n == NULL) ...
7.4 Les conversions de pointeurs
Il n’existe aucune conversion implicite d’un type pointeur dans un autre. En revanche, il est
toujours possible de faire appel à l’opérateur de cast. D’une manière générale, nous vous
conseillons de l’éviter, compte tenu des risques qu’elle comporte. En effet, on pourrait penser
qu’une telle conversion revient finalement à ne s’intéresser qu’à l’adresse correspondant à un
pointeur, sans s’intéresser au type de l’objet pointé.
Malheureusement, il faut tenir compte de ce que certaines machines imposent aux adresses
des objets ce que l’on appelle des « contraintes d’alignement ». Par exemple, un objet de 2 octets
sera toujours placé à une adresse paire, tandis qu’un caractère (objet d’un seul octet) pourra
être placé (heureusement) à n’importe quelle adresse. Dans ce cas, la conversion d’un char *
en un int * peut conduire soit à l’adresse effective du caractère lorsque celle-ci est paire, soit
à une adresse voisine lorsque celle-ci est impaire.
Delannoy Livre.book Page 135 Mercredi, 6. mai 2009 4:26 16
135
chapitre n° 7
Les tableaux et les pointeurs
7.2 La soustraction de pointeurs
Là encore, quand deux pointeurs sont de même type, leur différence fournit le nombre d’éléments du type en question situés entre les deux adresses correspondantes. L’emploi de cette
possibilité est assez rare.
7.3 Les affectations de pointeurs et le pointeur nul
Nous avons naturellement déjà rencontré des cas d’affectation de la valeur d’un pointeur à un
pointeur de même type. A priori, c’est le seul cas autorisé par le langage C (du moins, tant que
l’on ne procède pas à des conversions explicites). Une exception a toutefois lieu en ce qui
concerne la valeur entière 0, ainsi que pour le type générique void * dont nous parlerons un
peu plus loin. Cette tolérance est motivée par le besoin de pouvoir représenter un pointeur nul,
c’est-à-dire ne pointant sur rien (c’est le nil du Pascal). Bien entendu, cela n’a d’intérêt que
parce qu’il est possible de comparer n’importe quel pointeur (de n’importe quel type) avec ce
« pointeur nul ».
D’une manière générale, plutôt que la valeur 0, il est conseillé d’employer la constante NULL
prédéfinie dans stdio.h, et également dans stddef.h (bien entendu, elle sera remplacée
par la constante entière 0 lors du traitement par le préprocesseur, mais les programmes source
en seront néanmoins plus lisibles).
Avec ces déclarations :
int * n ;
double * x ;
ces instructions seront correctes :
n = 0 ;
/* ou mieux */ n = NULL ;
x = 0 ;
/* ou mieux */ x = NULL ;
if (n == 0) ...
/* ou mieux */ if (n == NULL) ...
7.4 Les conversions de pointeurs
Il n’existe aucune conversion implicite d’un type pointeur dans un autre. En revanche, il est
toujours possible de faire appel à l’opérateur de cast. D’une manière générale, nous vous
conseillons de l’éviter, compte tenu des risques qu’elle comporte. En effet, on pourrait penser
qu’une telle conversion revient finalement à ne s’intéresser qu’à l’adresse correspondant à un
pointeur, sans s’intéresser au type de l’objet pointé.
Malheureusement, il faut tenir compte de ce que certaines machines imposent aux adresses
des objets ce que l’on appelle des « contraintes d’alignement ». Par exemple, un objet de 2 octets
sera toujours placé à une adresse paire, tandis qu’un caractère (objet d’un seul octet) pourra
être placé (heureusement) à n’importe quelle adresse. Dans ce cas, la conversion d’un char *
en un int * peut conduire soit à l’adresse effective du caractère lorsque celle-ci est paire, soit
à une adresse voisine lorsque celle-ci est impaire.
Delannoy Livre.book Page 135 Mercredi, 6. mai 2009 4:26 16
