¿Diferencia entre char* y const char*?
Cuál es la diferencia entre
char* name
que apunta a una cadena literal constante, y
const char* name
char*
es un puntero mutable a un carácter/cadena mutable .
const char*
es un puntero mutable a un carácter/cadena inmutable . No puede cambiar el contenido de las ubicaciones a las que apunta este puntero. Además, los compiladores deben mostrar mensajes de error cuando intenta hacerlo. Por el mismo motivo, la conversión de const char *
a char*
está obsoleta.
char* const
es un puntero inmutable (no puede apuntar a ninguna otra ubicación), pero el contenido de la ubicación a la que apunta es mutable .
const char* const
es un puntero inmutable a un carácter/cadena inmutable .
char *name
Puede cambiar el carácter al que name
apunta y también el carácter al que apunta.
const char* name
Puede cambiar el carácter al que name
apunta, pero no puede modificar el carácter al que apunta.
corrección: Puede cambiar el puntero, pero no el carácter al que name
apunta ( https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx , consulte "Ejemplos" ). En este caso, el const
especificador se aplica a char
, no al asterisco.
Según la página de MSDN y http://en.cppreference.com/w/cpp/language/declarations , el const
antes *
es parte de la secuencia del especificador de decl, mientras que el const
después *
es parte del declarador.
Una secuencia de especificador de declaración puede ir seguida de múltiples declaradores, razón por la cual const char * c1, c2
se declara c1
as const char *
y c2
as const char
.
EDITAR:
Según los comentarios, su pregunta parece ser sobre la diferencia entre las dos declaraciones cuando el puntero apunta a una cadena literal.
En ese caso, no debes modificar el carácter al que name
apunta, ya que podría resultar en un comportamiento indefinido . Los literales de cadena se pueden asignar en regiones de memoria de solo lectura (definida por la implementación) y un programa de usuario no debe modificarlos de ninguna manera. Cualquier intento de hacerlo resulta en un comportamiento indefinido.
Entonces, la única diferencia en ese caso (de uso con cadenas literales) es que la segunda declaración le brinda una ligera ventaja. Los compiladores normalmente le darán una advertencia en caso de que intente modificar la cadena literal en el segundo caso.
Ejemplo de muestra en línea:
#include <string.h>
int main()
{
char *str1 = "string Literal";
const char *str2 = "string Literal";
char source[] = "Sample string";
strcpy(str1,source); //No warning or error, just Undefined Behavior
strcpy(str2,source); //Compiler issues a warning
return 0;
}
Producción:
cc1: las advertencias se tratan como errores
prog.c: en la función 'principal':
prog.c:9: error: pasar el argumento 1 de 'strcpy' descarta los calificadores del tipo de destino del puntero
Observe que el compilador advierte para el segundo caso pero no para el primero.