const
y volatile
son llamados "calificadores de tipo". Su sintaxis es una de las cosas más confusas en C.
En primer lugar tenemos el caso con una variable ordinaria. Por lo general, escribe el calificador de tipo antes del nombre de la variable: const int x;
, pero también está bien escribirlo después del nombre de la variable: int const x;
. El significado es el mismo, la última sintaxis está allí para confundir.
Al declarar un puntero, le preocupan dos tipos: el tipo del puntero en sí y el tipo al que apunta. Con los punteros ordinarios, esto es trivial: int* x
significa que el tipo de puntero es puntero-a-int, y el puntero-a-tipo es int.
Si el apuntado-a-tipo es const int, el puntero se declara como const int* x
. El puntero es de tipo pointer-to-const-int, y el tipo apuntado es const int. Si quiere confundir a todos, también puede escribir int const* x
, es equivalente.
Digamos que queremos que el puntero también sea constante. Por alguna razón, queremos bloquear al programador para que no cambie la dirección apuntada. Por ejemplo, tal vez el puntero debe almacenarse en la memoria de solo lectura de un sistema integrado. Un puntero constante a los datos, se declara como int*const x;
con la palabra clave const después del *. El tipo puntiagudo en este caso es int
y noconst int
.(Trato de escribir la const junto con el *, sin espacio en el medio, para dar énfasis que el puntero es constante)
Si queremos que la punta-a-tipo para que sea constante, así, tendríamos tiene que combinar las dos declaraciones anteriores: const int*const x;
significa un puntero constante apuntando a una constante int.
const int x; // x is a constant data variable
int const x; // x is a constant data variable
const int* x; // x is a non-constant pointer to constant data
int const* x; // x is a non-constant pointer to constant data
int*const x; // x is a constant pointer to non-constant data
const int*const x; // x is a constant pointer to constant data
En los ejemplos anteriores he utilizado el calificador de tipo const
. ¡Pero volatile
también es un calificador de tipo, y se comporta exactamente de la misma manera! Es posible declarar punteros no volátiles a datos volátiles, etc.
Y, por último, es posible combinar diferentes calificadores de tipo. Por ejemplo, un volatile const int*
es un puntero no constante y no volátil a los datos de const s volátiles. Una vez más, tenemos la maravillosa opción de mezclar el orden de estos para confundir, por lo que también podemos escribir volatile int const *
o int volatile const *
etc. y todo significa lo mismo.
+1, buena explicación de calificadores de tipo, pero el OP pregunta por qué se utiliza en su código – jeb
Gracias. Una pregunta rápida. ¿'Int * x' es equivalente a' int * int x'? – Randomblue
'volátil const int * ptr *' -> puntero a un dato que solo ha recibido permiso de lectura por el código, pero puede ser modificado por eventos externos (interrupciones, etc.) –