Diferencia entre char * y const char *?

Cuál es la diferencia entre

char* name 

que apunta a un literal de cadena 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, se requiere que los comstackdores den mensajes de error cuando intentas hacerlo. Por la misma razón, la conversión de const char * a char* está en desuso.

char* const es un puntero inmutable (no puede señalar a ninguna otra ubicación) pero el contenido de la ubicación en el que apunta es mutable .

const char* const es un puntero inmutable para un carácter / cadena inmutable .

 char *name 

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

 const char* name 

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

De acuerdo con la página de MSDN y http://en.cppreference.com/w/cpp/language/declarations , la const antes de * es parte de la secuencia del especificador de declinación, mientras que la const después de * es parte del declarador.
Una secuencia de especificador de statement puede ser seguida por múltiples declaradores, por lo que const char * c1, c2 declara c1 como const char * y c2 como const char .

EDITAR:

A partir de los comentarios, su pregunta parece estar preguntando sobre la diferencia entre las dos declaraciones cuando el puntero apunta a un literal de cadena.

En ese caso, no debe modificar el carácter al que apunta el name , ya que podría provocar un comportamiento no definido . Los literales de cadena pueden asignarse en regiones de memoria de solo lectura (implementación definida) y un progtwig de usuario no debería modificarlo de ninguna manera. Cualquier bash de hacerlo da como resultado un Comportamiento Indefinido.

Entonces la única diferencia en ese caso (de uso con literales de cadena) es que la segunda statement le da una ligera ventaja. Los comstackdores generalmente le darán una advertencia en caso de que intente modificar el literal de la cadena en el segundo caso.

Ejemplo de muestra en línea:

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

Salida:

cc1: advertencias que 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 objective de puntero

Observe que el comstackdor advierte para el segundo caso pero no para el primero.

 char mystring[101] = "My sample string"; const char * constcharp = mystring; // (1) char const * charconstp = mystring; // (2) the same as (1) char * const charpconst = mystring; // (3) constcharp++; // ok charconstp++; // ok charpconst++; // compile error constcharp[3] = '\0'; // compile error charconstp[3] = '\0'; // compile error charpconst[3] = '\0'; // ok // String literals char * lcharp = "My string literal"; const char * lconstcharp = "My string literal"; lcharp[0] = 'X'; // Segmentation fault (crash) during run-time lconstcharp[0] = 'X'; // compile error // *not* a string literal const char astr[101] = "My mutable string"; astr[0] = 'X'; // compile error ((char*)astr)[0] = 'X'; // ok 

En ninguno de los casos puede modificar un literal de cadena, independientemente de si el puntero a ese literal de cadena se declara como char * o const char * .

Sin embargo, la diferencia es que si el puntero es const char * , el comstackdor debe dar un diagnóstico si intenta modificar el valor apuntado, pero si el puntero es char * no lo hace.

El primero que realmente puede cambiar si lo desea, el segundo no puede. Lea acerca de la exactitud const (hay algunas buenas guías sobre la diferencia). También hay un char const * name donde no puede volver a marcarlo.

En realidad, el char* name no es un puntero a una constante, sino un puntero a una variable. Usted podría estar hablando de esta otra pregunta.

¿Cuál es la diferencia entre char * const y const char *?

CASO 1:

 char *str = "Hello"; str[0] = 'M' //No warning or error, just Undefined Behavior 

Lo anterior establece str para apuntar al valor literal “Hello”, que está codificado en la imagen binaria del progtwig, que está marcada como de solo lectura en la memoria, significa que cualquier cambio en este literal de Cadena es ilegal y arrojaría fallas de segmentación.

CASO 2:

 const char *str = "Hello"; str[0] = 'M' //Compiler issues a warning 

CASO 3:

 char str[] = "Hello"; str[0] = 'M'; // legal and change the str = "Mello". 

Solo para dar un ejemplo extra:

  std::cout << typeid(2.3).name() << '\n'; // -----> prints "double" simply because //2.3 is a double //But the "double" returned by typeid(2.3).name() is indeed a //const char * which consists of 'd','o','u','b','l','e'and'\0'. //Here's a simple proof to this: std::cout << typeid(typeid(2.3).name()).name() << '\n'; //prints: "const char *" const char* charptr charptr = typeid(2.3).name(); std::cout << charptr[3]; // ---------> prints: "b" 

(Estoy usando la biblioteca typeinfo: http://www.cplusplus.com/reference/typeinfo/type_info/name )

  //Now let's do something more interesting: char* charptr2="hubble"; strcpy(charptr, charptr2); // --------> Oops! Sorry, this is not valid! 

Puede ejecutarlo y ver las cosas mejor para usted.

La pregunta es ¿cuál es la diferencia entre

 char *name 

que apunta a un literal de cadena constante, y

 const char *cname 

Es decir,

 char *name = "foo"; 

y

 const char *cname = "foo"; 

No hay mucha diferencia entre los 2 y ambos se pueden ver como correctos. Debido al largo legado del código C, los literales de cadena han tenido un tipo de char[] , no const char[] , y hay muchos códigos anteriores que también aceptan char * lugar de const char * , incluso cuando no lo hacen modificar los argumentos.

La principal diferencia de los 2 en general es que *cname o cname[n] evaluará a lvalues ​​de tipo const char , mientras que *name o name[n] evaluará a lvalues ​​de tipo char , que son valores modificables . Se requiere un comstackdor conforme para generar un mensaje de diagnóstico si el objective de la asignación no es un valor l modificable ; no necesita producir ninguna advertencia en la asignación a lvalues ​​de tipo char :

 name[0] = 'x'; // no diagnostics *needed* cname[0] = 'x'; // a conforming compiler *must* produce a diagnostics message 

El comstackdor no está obligado a detener la comstackción en ningún caso; es suficiente que produzca una advertencia para la asignación a cname[0] . El progtwig resultante no es un progtwig correcto . El comportamiento de la construcción no está definido . Puede fallar, o incluso peor, puede no bloquearse, y puede cambiar el literal de la cadena en la memoria.