Cuál es la diferencia entre:
char * const
y
const char *
libra
Cuál es la diferencia entre:
char * const
y
const char *
trabajomad3
la diferencia es que const char *
es un puntero a un const char
mientras char * const
es un puntero constante a un char
.
El primero, el valor al que se apunta no se puede cambiar, pero el puntero sí. El segundo, el valor al que se apunta puede cambiar pero el puntero no (similar a una referencia).
También hay una
const char * const
que es un puntero constante a un carácter constante (por lo que no se puede cambiar nada al respecto).
Nota:
Las dos formas siguientes son equivalentes:
const char *
y
char const *
El motivo exacto de esto se describe en el estándar C++, pero es importante tenerlo en cuenta y evitar confusiones. Conozco varios estándares de codificación que prefieren:
char const
terminado
const char
(con o sin puntero) para que la colocación de la const
elemento es lo mismo que con un puntero const
.
¿Valdría la pena observar qué sucede si se especifican múltiples variables en la misma declaración? Yo creo const int *foo,*bar;
declararía ambos foo
y bar
ser – estar int const *
pero int const *foo, *bar
declararía foo
ser un int const *
y bar
ser – estar int *
. pienso typedef int * intptr; const intptr foo,bar;
declararía que ambas variables son int * const
; No conozco ninguna forma de usar una declaración combinada para crear dos variables de ese tipo sin un typedef.
– Super gato
12/04/2013 a las 21:57
@Super gato I believe const int *foo,*bar; would declare both foo and bar to be int const *
: Sí. but int const *foo, *bar would declare foo to be a int const * and bar to be int *
: ¡No! Sería exactamente igual que el caso anterior. (Ver ideone.com/RsaB7n donde obtienes el mismo error tanto para foo como para bar). I think typedef int * intptr; const intptr foo,bar; would declare both variables to be int * const
: Sí. I don't know any way to use a combined declaration to create two variables of that type without a typedef
: Bien, int *const foo, *const bar;
. Sintaxis del declarador C…
– gx_
28/08/2013 a las 18:35
@gx_: Así que me equivoqué; mi duda era por qué sugerí que podría ser útil decir cuáles son las reglas. que seria int const *foo, *volatile bar
hacer para bar
? hazlo ambos const
y volatile
? Echo de menos la separación limpia de Pascal de nombres de variables declaradas y sus tipos (un puntero a una matriz de punteros a enteros sería var foo: ^Array[3..4] of ^Integer
;`. Eso sería algo divertido entre paréntesis anidado en C, creo.
– Super gato
28 de agosto de 2013 a las 18:54
@supercat (oh, solo C, perdón por el enlace del código C++, llegué aquí por una pregunta de C++) Se trata de la Sintaxis de declaración Ccon un (“puro”) tipo parte seguida de una declarante. En “int const *foo, *volatile bar
” la parte tipo es int const
(Se detiene ante el *
) y los declarantes son *foo
(la expresion *foo
denotará un int const
) y *volatile bar
; leyendo De derecha a izquierda (buena regla para cv-calificadores), foo
es un puntero a un constante int, y bar
es un volátil puntero a un constante int (el puntero en sí es volátil, el int apuntado es [accessed as] constante).
– gx_
28 de agosto de 2013 a las 21:23
@supercat Y en cuanto a “un puntero a una matriz de punteros a números enteros” (no conozco a Pascal, no estoy seguro del [3..4]
sintaxis, así que tomemos una matriz de 10 elementos): int *(*foo)[10];
. Refleja su uso (futuro) como una expresión: *(*foo)[i]
(con i
un entero en el rango [0, 10)
i.e. [0, 9]
) primero desreferenciará foo
para llegar a la matriz, luego acceda al elemento en el índice i
(porque sufijo []
se une más fuerte que el prefijo *
), luego elimine la referencia de este elemento, finalmente produciendo un int
(ver ideone.com/jgjIjR ). Pero typedef
hace que sea más fácil (ver ideone.com/O3wb7d ).
– gx_
28 de agosto de 2013 a las 21:25
Para evitar confusiones, siempre adjuntar el calificador const.
int * mutable_pointer_to_mutable_int;
int const * mutable_pointer_to_constant_int;
int *const constant_pointer_to_mutable_int;
int const *const constant_pointer_to_constant_int;
¿Por qué? “Para evitar confusiones” no explica cuál es la confusión para mí.
– Andrew Weir
20 de noviembre de 2013 a las 11:48
@Andrew: Estaba insinuando consistencia y, por lo tanto, legibilidad. Escribir todos los calificadores de tipo para que modifiquen lo que está a su izquierda, siemprees lo que uso.
– diapiro
20 de noviembre de 2013 a las 14:31
En realidad, es la mejor respuesta sobre el tema que he encontrado en SO
– Trampa
22 de abril de 2014 a las 15:51
Como estándar de código, rara vez me he encontrado con este estilo y, por lo tanto, no es probable que lo adopte. Sin embargo, como herramienta de aprendizaje, ¡esta respuesta fue muy útil! (Así que supongo que es una lástima que este no sea un estilo más común).
– natevw
29/09/2014 a las 21:33
@alla: p
no se relaciona con el tipo: (const int *const)
. Para bien o para mal (peor si me preguntas), el calificador const, tanto en C como en C++, debe ser un postfijo: función de miembro cf const void foo(int a) const;
. La posibilidad de declarar const int
es la excepción y no la regla.
– diapiro
9 de abril de 2015 a las 7:17
Otra regla general es comprobar dónde constante es:
const
siempre modifica lo que viene antes (a la izquierda), EXCEPTO cuando es lo primero en una declaración de tipo, donde modifica lo que viene después (a la derecha).
Entonces estos dos son iguales:
int const *i1;
const int *i2;
definen punteros a un const int
. Puedes cambiar de lugar i1
y i2
puntos, pero no puede cambiar el valor al que apuntan.
Este:
int *const i3 = (int*) 0x12345678;
define un const
puntero a un número entero y lo inicializa para que apunte a la ubicación de memoria 12345678. Puede cambiar el int
valor en la dirección 12345678, pero no puede cambiar la dirección que i3
puntos a.
Regla de oro: ¡Lea la definición de derecha a izquierda!
const int *foo;
Significa “foo
puntos (*
) a una int
que no puede cambiar (const
)”.
Para el programador esto significa “No cambiaré el valor de que foo
puntos a”.
*foo = 123;
o foo[0] = 123;
sería inválido.foo = &bar;
esta permitido.int *const foo;
Significa “foo
no puede cambiar (const
) y puntos (*
) a una int
“.
Para el programador esto significa “No cambiaré el dirección de memoria ese foo
se refiere a”.
*foo = 123;
o foo[0] = 123;
esta permitido.foo = &bar;
sería inválido.const int *const foo;
Significa “foo
no puede cambiar (const
) y puntos (*
) a una int
que no puede cambiar (const
)”.
Para el programador esto significa “No cambiaré el valor de que foo
apunta a, ni voy a cambiar el dirección ese foo
se refiere a”.
*foo = 123;
o foo[0] = 123;
sería inválido.foo = &bar;
sería inválido.const char*
es un puntero a un carácter constante
char* const
es un puntero constante a un carácter
const char* const
es un puntero constante a un carácter constante
Evan Carroll
carácter constante* x Aquí X es básicamente un puntero de carácter que apunta a un valor constante
char* constante x se refiere al puntero de carácter que es constante, pero la ubicación a la que apunta se puede cambiar.
const char* const x es una combinación de 1 y 2, significa que es un puntero de carácter constante que apunta a un valor constante.
const *char x provocará un error del compilador. no se puede declarar.
const char * x es igual al punto 1.
la regla general es si constante es con var nombre entonces el el puntero será constante pero la ubicación que apunta se puede cambiar demás el puntero apuntará a una ubicación constante y el puntero puede apuntar a otra ubicación, pero el contenido de la ubicación que apunta no se puede cambiar.
“char* const x se refiere al puntero de carácter que es constante, pero la ubicación a la que apunta se puede cambiar”. Equivocado. El valor en la ubicación se puede cambiar, no la ubicación en sí.
– Por favor ayuda
12 de marzo de 2015 a las 13:44
Posible duplicado de ¿Cuál es la diferencia entre const int*, const int * const e int const *?
– Emlai
14 de febrero de 2016 a las 13:07
Lo primero a la izquierda de “const” es lo que es constante. Si “const” es lo que está más a la izquierda, entonces lo primero a la derecha es lo que es constante.
– Magdalena
31 de julio de 2016 a las 4:43
Como consejo amistoso, nunca olvides que cdecl es una cosa
– Braden Mejor
16 de junio de 2018 a las 7:42
Hay otro char const* que es el tipo de retorno de excepción::qué()
– Zhang
22 de julio de 2019 a las 3:14
Preguntas frecuentes sobre ISO C++: ¿Cuál es la diferencia entre “const X* p”, “X* const p” y “const X* const p”?
– leyendas2k
21 de septiembre de 2020 a las 16:25