Une grande confusion sur les pointeurs C vient d'un très mauvais choix qui a été fait à l'origine concernant le style de codage, corroboré par un très mauvais petit choix dans la syntaxe du langage.
int *x = NULL;
est correct C, mais il est très trompeur, je dirais même absurde, et cela a gêné la compréhension de la langue pour de nombreux novices. Cela fait penser que plus tard, nous pourrions faire *x = NULL;
ce qui est bien sûr impossible. Vous voyez, le type de la variable n'est pas int
, et le nom de la variable ne l'est pas *x
, et le *
dans la déclaration ne joue aucun rôle fonctionnel en collaboration avec le =
. C'est purement déclaratif. Donc, ce qui a beaucoup plus de sens, c'est ceci:
int* x = NULL;
ce qui est également correct C, bien qu'il n'adhère pas au style de codage K&R d'origine. Cela rend parfaitement clair que le type est int*
et que la variable de pointeur est x
, de sorte qu'il devient clairement évident, même pour les non-initiés, que la valeur NULL
est stockée dans x
, qui est un pointeur vers int
.
De plus, cela facilite la dérivation d'une règle: lorsque l'étoile est éloignée du nom de la variable, il s'agit d'une déclaration, tandis que l'étoile attachée au nom est un déréférencement de pointeur.
Donc, maintenant, il devient beaucoup plus compréhensible que plus bas, nous pouvons le faire x = NULL;
ou *x = 2;
en d'autres termes, il est plus facile pour un novice de voir comment variable = expression
mène à pointer-type variable = pointer-expression
et dereferenced-pointer-variable = expression
. (Pour les initiés, par «expression», je veux dire «rvalue».)
Le choix malheureux dans la syntaxe du langage est que lors de la déclaration de variables locales, vous pouvez dire int i, *p;
qui déclare un entier et un pointeur vers un entier, cela laisse donc penser que le *
est une partie utile du nom. Mais ce n'est pas le cas, et cette syntaxe n'est qu'un cas spécial excentrique, ajouté par commodité, et à mon avis, elle n'aurait jamais dû exister, car elle invalide la règle que j'ai proposée ci-dessus. Autant que je sache, nulle part ailleurs dans le langage cette syntaxe n'a de sens, mais même si c'est le cas, elle indique une divergence dans la façon dont les types de pointeurs sont définis en C. Partout ailleurs, dans les déclarations à variable unique, dans les listes de paramètres, dans les membres de structure, etc., vous pouvez déclarer vos pointeurs comme type* pointer-variable
au lieu de type *pointer-variable
; c'est parfaitement légal et a plus de sens.
int *x = whatever;
fait et ce quiint *x; *x = whatever;
fait.int *x = whatever;
se comporte réellement commeint *x; x = whatever;
, non*x = whatever;
.