¿Diferencia entre char* y const char*?

Resuelto Iceman asked hace 12 años • 9 respuestas

Cuál es la diferencia entre

char* name

que apunta a una cadena literal constante, y

const char* name
Iceman avatar Mar 23 '12 11:03 Iceman
Aceptado

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* constes 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* constes un puntero inmutable a un carácter/cadena inmutable .

ankit.karwasra avatar Mar 23 '2012 04:03 ankit.karwasra
char *name

Puede cambiar el carácter al que nameapunta y también el carácter al que apunta.

const char* name

Puede cambiar el carácter al que nameapunta, pero no puede modificar el carácter al que apunta.
corrección: Puede cambiar el puntero, pero no el carácter al que nameapunta ( https://msdn.microsoft.com/en-us/library/vstudio/whkd4k6a(v=vs.100).aspx , consulte "Ejemplos" ). En este caso, el constespecificador se aplica a char, no al asterisco.

Según la página de MSDN y http://en.cppreference.com/w/cpp/language/declarations , el constantes *es parte de la secuencia del especificador de decl, mientras que el constdespué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, c2se declara c1as const char *y c2as 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 nameapunta, 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.

Alok Save avatar Mar 23 '2012 04:03 Alok Save