puntero constante contra puntero en un valor constante

¿Cuál es la diferencia entre las siguientes declaraciones?

char * const a; const char * a; 

Para entender la diferencia, escribí este pequeño progtwig:

 #include  #include  int main (int argc, char **argv) { char a = 'x'; char b = 'y'; char * const pc1 = &a; const char * pc2 = &a; printf ("Before\n"); printf ("pc1=%p\n", pc1); printf ("*pc1=%c\n", *pc1); printf ("pc2=%p\n", pc2); printf ("*pc2=%c\n", *pc2); *pc1 = b; /* pc1 = &b; */ /* *pc2 = b; */ pc2 = &b; printf ("\n\n"); printf ("After\n"); printf ("pc1=%p\n", pc1); printf ("*pc1=%c\n", *pc1); printf ("pc2=%p\n", pc2); printf ("*pc2=%c\n", *pc2); return EXIT_SUCCESS; } 

Recopilé el progtwig (con gcc 3.4) y lo ejecuté. El resultado destaca la diferencia bastante bien:

 Before pc1=ffbfd7e7 *pc1=x pc2=ffbfd7e7 *pc2=x After pc1=ffbfd7e7 *pc1=y pc2=ffbfd7e6 *pc2=x 

Sin embargo, tuve que escribir el pequeño progtwig para obtener la respuesta. En caso de que esté lejos de la máquina (en una entrevista, por ejemplo), no podría responder la pregunta.

¿Puede alguien explicar, mediante un comentario del ejemplo anterior, cómo funciona la palabra clave const ?

 char * const a; 

significa que el puntero es constante e inmutable, pero los datos apuntados no lo son.
Puede usar const_cast (en C ++) o molde de estilo c para descartar la constness en este caso ya que los datos en sí mismos no son constantes.

 const char * a; 

significa que los datos apuntados no se pueden escribir utilizando el puntero a. El uso de un const_cast (C ++) o c-style para descartar la constness en este caso causa un comportamiento indefinido .

Para analizar tipos complicados, comienzas en la variable, ve a la izquierda y en espiral hacia afuera. Si no hay ninguna matriz o función de la que preocuparse (porque se encuentran a la derecha del nombre de la variable), esto se convierte en un caso de lectura de derecha a izquierda.

Entonces con char *const a; usted tiene a , que es un puntero de const ( * ) a un char . En otras palabras, puede cambiar el carácter al que señala a, pero no puede señalar algo diferente.

A la inversa con const char* b; tienes b , que es un puntero ( * ) a un char que es const . Puedes hacer b point en cualquier char que quieras, pero no puedes cambiar el valor de ese char usando *b = ...; .

También puede, por supuesto, tener los dos sabores de la consistencia al mismo tiempo: const char *const c; .

 char * const a; 

*a es escribible, pero a no es; en otras palabras, puede modificar el valor apuntado por a , pero no puede modificar a mismo. a es un puntero constante a char .

 const char * a; 

a es escribible, pero *a no es; en otras palabras, puede modificar a (apuntándola a una nueva ubicación), pero no puede modificar el valor apuntado por a .

Tenga en cuenta que esto es idéntico a

 char const * a; 

En este caso, a es un puntero a un const char .

Ahora que sabes la diferencia entre char * const a y const char * a . Muchas veces nos confundimos si es un puntero constante o un puntero a una variable constante.

Cómo leerlo? Siga el siguiente paso simple para identificar entre los dos superiores.

Veamos cómo leer a continuación la statement

 char * const a; 

Lee de derecha a izquierda

Ahora comienza con a ,

1. adyacente a a hay const .

char * (const a) ;

—> Entonces a es una constant (????) .

2. Ahora adelante, obtén *

char (* (const a)) ;

—> Entonces a es un pointer constant a (????) .

3. Vete y hay char

(char (* (const a))) ;

—> a es un pointer constant a la variable de character

 a is constant pointer to character variable. 

¿No es fácil de leer?

Similarmente para la segunda statement

 const char * a; 

Ahora comienza de nuevo con a ,

1. Adyacente a a hay *

—> Así que a es un pointer a (????)

2. Ahora hay char

—> así que a es a character pointer ,

Bueno, eso no tiene ningún sentido! Así que baraja el pointer y el character

—> entonces a es a pointer character a (?????)

3. Ahora tienes constant

—> entonces a es pointer character a variable constant

Pero aunque pueda distinguir qué significa la statement, hagamos que suene más sensato.

 a is pointer to constant character variable 

La forma más fácil de entender la diferencia es pensar en las diferentes posibilidades. Hay dos objetos a considerar, el puntero y el objeto apuntado (en este caso ‘a’ es el nombre del puntero, el objeto apuntado no tiene nombre, de tipo char). Las posibilidades son:

  1. nada es const
  2. el puntero es const
  3. el objeto apuntado es const
  4. tanto el puntero como el objeto apuntado son const.

Estas diferentes posibilidades se pueden express en C de la siguiente manera:

  1. char * a;
  2. char * const a;
  3. const char * a;
  4. const char * const a;

Espero que esto ilustre las posibles diferencias

El primero es un puntero constante a un char y el segundo es un puntero a un char constante. No tocaste todos los casos en tu código:

 char * const pc1 = &a; /* You can't make pc1 point to anything else */ const char * pc2 = &a; /* You can't dereference pc2 to write. */ *pc1 = 'c' /* Legal. */ *pc2 = 'c' /* Illegal. */ pc1 = &b; /* Illegal, pc1 is a constant pointer. */ pc2 = &b; /* Legal, pc2 itself is not constant. */ 

Primero lo explicaré verbalmente y luego con un ejemplo:

Un objeto de puntero puede declararse como un puntero const o un puntero a un objeto const (o ambos):

Un puntero de const no se puede reasignar para apuntar a un objeto diferente del que se le asignó inicialmente, pero se puede usar para modificar el objeto al que apunta (llamado “pointee”).
Las variables de referencia son, por lo tanto, una syntax alternativa para los constpointers.

Un puntero a un objeto const , por otro lado, puede reasignarse para apuntar a otro objeto del mismo tipo o de un tipo convertible, pero no puede usarse para modificar ningún objeto.

También se puede declarar un puntero const para un objeto const y no se puede usar para modificar el puntero ni reasignarlo para apuntar a otro objeto.

Ejemplo:

 void Foo( int * ptr, int const * ptrToConst, int * const constPtr, int const * const constPtrToConst ) { *ptr = 0; // OK: modifies the "pointee" data ptr = 0; // OK: modifies the pointer *ptrToConst = 0; // Error! Cannot modify the "pointee" data ptrToConst = 0; // OK: modifies the pointer *constPtr = 0; // OK: modifies the "pointee" data constPtr = 0; // Error! Cannot modify the pointer *constPtrToConst = 0; // Error! Cannot modify the "pointee" data constPtrToConst = 0; // Error! Cannot modify the pointer } 

¡Feliz de ayudar! ¡Buena suerte!

Arriba hay excelentes respuestas. Aquí hay una manera fácil de recordar esto:

a es un puntero

* a es el valor

Ahora si dices “const a”, entonces el puntero es const. (es decir, char * const a;)

Si dice “const * a”, entonces el valor es const. (es decir, const char * a;)

Puede usar la utilidad cdecl o sus versiones en línea, como https://cdecl.org/

Por ejemplo:

void (* x)(int (*[])()); es un declare x as pointer to function (array of pointer to function returning int) returning void

Intentando responder de manera simple:

 char * const a; => a is (const) constant (*) pointer of type char {L <- R}. =>( Constant Pointer ) const char * a; => a is (*) pointer to char constant {L <- R}. =>( Pointer to Constant) 

Puntero constante:

el puntero es constante !! es decir, la dirección que está sosteniendo no se puede cambiar. Se almacenará en la memoria de solo lectura.

Intentemos cambiar la dirección del puntero para entender más:

 char * const a = &b; char c; a = &c; // illegal , you can't change the address. `a` is const at L-value, so can't change. `a` is read-only variable. 

Significa que una vez punteros constantes algo es para siempre.

puntero a puntos solo b .

Sin embargo, puede cambiar el valor de b por ejemplo:

 char b='a'; char * const a =&b; printf("\n print a : [%c]\n",*a); *a = 'c'; printf("\n now print a : [%c]\n",*a); 

Puntero a constante:

El valor apuntado por el puntero no se puede cambiar.

 const char *a; char b = 'b'; const char * a =&b; char c; a=&c; //legal *a = 'c'; // illegal , *a is pointer to constant can't change!. 
 const char * a; 

Esto indica puntero a carácter constante. Por ej.

 char b='s'; const char *a = &b; 

Aquí a apunta a un char constante (‘s’, en este caso). No puede usar a para cambiar ese valor. Pero esta statement no significa que el valor al que apunta es realmente una constante , solo significa el valor es una constante en lo que se refiere a a. Puede cambiar el valor de b directamente cambiando el valor de b , pero no puede cambiar el valor indirectamente mediante el puntero a.

*a='t'; //INVALID b='t' ; //VALID

 char * const a=&b 

Esto establece un puntero constante a char. Restringe a apuntar solo a b pero le permite alterar el valor de b .

¡¡¡Espero eso ayude!!! 🙂