puntero constante vs puntero en un valor constante [duplicado]


Esta pregunta ya tiene una respuesta aquí:

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

char * const a;
const char * a;

Para entender la diferencia escribí este pequeño programa:

#include <stdio.h>
#include <stdlib.h>


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;
}

Compilé el programa (con gcc 3.4) y lo ejecuté. El la salida resalta 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 programa para obtener la respuesta. En caso de que esté lejos de la máquina (en una entrevista, por ejemplo), no sería capaz de responder a la pregunta.

¿Puede alguien explicar, comentando el ejemplo anterior, cómo funciona la palabra clave const?

Author: another, 2012-04-10

11 answers

char * const a;

Significa que el puntero es constante e inmutable, pero los datos apuntados no lo son.
Podría usar const_cast(en C++) o c-style cast para descartar la constancia en este caso, ya que los datos en sí no son constantes.

const char * a;

Significa que los datos apuntados no se pueden escribir usando el puntero a. El uso de const_cast(C++) o c-style cast para desechar la constancia en este caso causa Un Comportamiento indefinido.

 161
Author: Alok Save,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-26 23:39:08

Para analizar tipos complicados, se empieza por la variable, se va a la izquierda y se hace una espiral hacia el exterior. Si no hay matrices o funciones de las 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.

Así que con char *const a; tienes a, que es un puntero const (*) a un char. En otras palabras, puedes cambiar el carácter al que a apunta, pero no puedes hacer que a apunte a nada diferente.

A la inversa con const char* b; tienes b, que es un puntero (*) a un char que es const. Puede hacer que b apunte a cualquier carácter que desee, pero no puede cambiar el valor de ese carácter usando *b = ...;.

También puedes, por supuesto, tener ambos sabores de constancia a la vez: const char *const c;.

 74
Author: AAT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-20 09:11:11
char * const a;

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

const char * a; 

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

Tenga en cuenta que esto es idéntico a

char const * a;

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

 59
Author: John Bode,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-20 08:34:13

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

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

Vamos a ver cómo leer a continuación declaración

char * const a;

Leer de derecha a izquierda

Ahora comienza con a,

1 . adyacente a a está const.

Char * (const a);

- - - > Así que a es un constant (????).

2 . Ahora ve a lo largo tienes *

Char (* (const a));

- - - > So a is a constant pointer a (????).

3 . Sigue adelante y hay char {[46]]}

(char (* (const a)));

---> a es un constant pointer a character variable

a is constant pointer to character variable. 

No es fácil de leer?

Análogamente para la segunda declaración

const char * a;

Ahora de nuevo comienza con a,

1 . Adyacente a a hay *

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

2 . Ahora hay char

- - - > así que a es pointer character,

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

- - - > así que a es character pointer a (?????)

3 . Ahora tienes constant

- - - > así que a es character pointer a constant variable

Pero aunque se puede distinguir lo que significa la declaración, hagamos que suene más sensato.

a is pointer to constant character variable
 21
Author: Sagar Sakre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-12 08:57:22

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 señalado es const
  4. tanto el puntero como el objeto apuntado a son constantes.

Estos diferentes las posibilidades pueden expresarse 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

 13
Author: John Vincent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-13 09:54:54

El primero es un puntero constante a un carácter y el segundo es un puntero a un carácter 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. */
 12
Author: cnicutar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-10 15:39:57

Lo explicaré verbalmente primero y luego con un ejemplo:

Un objeto puntero se puede declarar como un puntero const o un puntero a un objeto const (o ambos):

A const pointer no se puede reasignar para apuntar a un objeto diferente del que está asignado inicialmente, pero se puede usar para modificar el objeto al que apunta (llamado "pointee").
Las variables de referencia son, por lo tanto, una sintaxis alternativa para los constpointers.

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

Un puntero const a un objeto const también se puede declarar y no se puede usar para modificar el pointee ni se puede reasignar 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!

 6
Author: Barel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-03 16:43:55

Arriba hay grandes 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 dices "const *a" entonces el valor es const. (es decir, const char * a;)

 5
Author: jack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-25 15:29:20

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

 2
Author: Zinovy Nis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-22 04:48:46

Tratando de 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 tiene no se puede cambiar. Se almacenará en la memoria de solo lectura.

Tratemos de 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 que el puntero constante señala alguna cosa, es para siempre.

Pointer a points only b.

Sin embargo, puede cambiar el valor de b eg:

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!.
 1
Author: B_San,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-13 17:30:19
const char * a;

Este estado puntero a carácter constante. Por ejemplo.

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

Aquí a apunta a una constante char('s',en este caso).No puede usar a para cambiar ese valor.Pero esta declaración no significa que el valor al que apunta sea realmente una constante,solo significa que el valor es una constante en lo que respecta a a. Puede cambiar el valor de b directamente cambiando el valor de b, pero no puede cambiar el valor indirectamente a través de a puntero.

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

char * const a=&b

Esto establece un puntero constante a char. Limita a a apuntar solo a b sin embargo le permite alterar el valor de b.

Espero que ayude!!! :)

 0
Author: user4291320,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-31 08:04:36