Mucha confusión acerca de los punteros C proviene de una muy mala elección que se hizo originalmente con respecto al estilo de codificación, corroborada por una muy mala elección en la sintaxis del lenguaje.
int *x = NULL;
C es correcta, pero es muy engañosa, incluso diría absurda, y ha dificultado la comprensión del idioma para muchos novatos. Hace pensar que más adelante podríamos hacer lo *x = NULL;
que, por supuesto, es imposible. Verá, el tipo de la variable no lo es int
, y el nombre de la variable no lo es *x
, ni el *
en la declaración juega ningún papel funcional en colaboración con el =
. Es puramente declarativo. Entonces, lo que tiene mucho más sentido es esto:
int* x = NULL;
que también es C correcta, aunque no se adhiere al estilo de codificación original de K&R. Deja perfectamente claro que el tipo es int*
, y la variable de puntero lo es x
, por lo que resulta claramente evidente incluso para los no iniciados que el valor NULL
se está almacenando en x
, que es un puntero a int
.
Además, hace que sea más fácil derivar una regla: cuando la estrella está lejos del nombre de la variable, entonces es una declaración, mientras que la estrella que se adjunta al nombre es una desreferenciación del puntero.
Entonces, ahora se vuelve mucho más comprensible que más abajo podamos hacer x = NULL;
o, *x = 2;
en otras palabras, facilita que un novato vea cómo variable = expression
conduce a pointer-type variable = pointer-expression
y dereferenced-pointer-variable = expression
. (Para los iniciados, por 'expresión' me refiero a 'rvalue').
La desafortunada elección en la sintaxis del lenguaje es que al declarar variables locales puedes decir int i, *p;
cuál declara un número entero y un puntero a un número entero, por lo que te lleva a creer que *
es una parte útil del nombre. Pero no lo es, y esta sintaxis es solo un caso especial peculiar, agregado por conveniencia y, en mi opinión, nunca debería haber existido, porque invalida la regla que propuse anteriormente. Hasta donde yo sé, en ninguna otra parte del lenguaje esta sintaxis es significativa, pero incluso si lo es, apunta a una discrepancia en la forma en que se definen los tipos de puntero en C.En cualquier otro lugar, en declaraciones de una sola variable, en listas de parámetros, en miembros de estructura, etc., puede declarar sus punteros como en type* pointer-variable
lugar de type *pointer-variable
; es perfectamente legal y tiene más sentido.
int *x = whatever;
hace y lo queint *x; *x = whatever;
hace.int *x = whatever;
en realidad se comporta comoint *x; x = whatever;
, no*x = whatever;
.