Para conseguir que el puntero sea inalterable, debe colocar el especificador const a la derecha del *:
int d = 1; int * const w = &d;
Ahora, se lee «w es un puntero constante, y apunta a un int». Como el puntero en sí es ahora una constante, el compilador obliga a darle un valor inicial que no podrá alterarse durante la vida del puntero. Sin embargo, sí puede cambiar el valor de aquello a lo que apunta el puntero con algo como:
*w = 2;
También puede hacer un puntero constante a un elemento constante usando una de las formas siguientes:
int d = 1; const int* const x = &d; // (1) int const* const x2 = &d; // (2)
Ahora ni el puntero ni el elemento al que apunta pueden modificarse.
Algunos argumentan que la segunda forma es más coherente porque el const se coloca siempre a la derecha de lo que afecta. Debe decidir qué forma resulta más clara para su estilo de codificación particular.
Éstas son las líneas anteriores en un fichero compilable:
//: C08:ConstPointers.cpp const int* u; int const* v; int d = 1; int* const w = &d; const int* const x = &d; // (1) int const* const x2 = &d; // (2) int main() {} ///:~
Listado 8.3. C08/ConstPointers.cpp
Este libro sigue la norma de poner sólo una definición de puntero por línea, e inicializar cada puntero en el punto de definición siempre que sea posible. Por eso, es posible usar el estilo de «pegar» el * al tipo de dato:
int* u = &i;
como si int* fuese un tipo en sí mismo. Esto hace que el código sea más fácil de leer, pero desafortunadamente, ésta no es la forma en que funciona. El «*» se refiere al identificador, no al tipo. Se puede colocar en cualquier sitio entre el nombre del tipo y el identificador. De modo que puede hacer esto:
int * u = &i, v = 0;
donde se crea un int* u y después un int v (que no es puntero). Como esto puede parecer confuso a los lectores, es mejor utilizar el estilo mostrado en este libro.