pointer - structure in c++
¿cómo es char*a string literal válido? (5)
Entonces, desde mi comprensión, las variables del puntero apuntan a una dirección. Entonces, ¿cómo es el siguiente código válido en C ++?
char* b= "abcd"; //valid
int *c= 1; //invalid
En C y versiones muy antiguas de C ++, una cadena literal "abcd" es de tipo char[] , una matriz de caracteres. Tal matriz puede ser apuntada naturalmente por un char* , pero no por un int* ya que ese no es un tipo compatible.
Sin embargo, C y C ++ son diferentes, a menudo incompatibles lenguajes de programación. Dejaron de compatibilidad entre ellos hace unos 20 años.
En C ++ estándar, un literal de cadena es de tipo const char[] y, por lo tanto, ninguno de los códigos publicados es válido en C ++. Esto no compilará
char* b = "abcd"; //invalid, discards const qualifier
Esta voluntad:
const char* c = "abcd"; // valid
La primera linea
char* b= "abcd";
es válido en C, porque "cadenas literales", mientras se usa como inicializador, se reduce a la dirección del primer elemento en el literal, que es un puntero (a char ).
Relacionados, C11 , capítulo §6.4.5, literales de cadenas,
[...] La secuencia de caracteres multibyte se usa para inicializar una matriz de duración de almacenamiento estático y longitud suficiente para contener la secuencia. Para los literales de cadena de caracteres, los elementos de la matriz tienen tipo
char, y se inicializan con los bytes individuales de la secuencia de caracteres multibyte. [...]
y luego, capítulo §6.3.2.1 ( énfasis mío )
Excepto cuando es el operando del operador
sizeof, el operador_Alignof, o el operador unario, o es un literal de cadena usado para inicializar una matriz , una expresión que tiene tipo '''' matriz de tipo '''' se convierte a una expresión con escriba '''' puntero al tipo '''' que apunta al elemento inicial del objeto de la matriz y no es un valor l.
Sin embargo, como se menciona en los comentarios, en C++11 adelante, esto ya no es válido ya que los literales de cadena son de tipo const char[] allí y en su caso, LHS carece del especificador const .
OTOH,
int *c= 1;
es inválido (ilegal) porque, 1 es una constante entera, que no es del mismo tipo que int * .
Si bien todas las otras respuestas dan la respuesta correcta de por qué el código no funciona, usar un literal compuesto para inicializar c , es una forma de hacer que el código funcione, por ejemplo
int *c= (int[]){ 1 };
printf ("int pointer c : %d/n", *c);
Tenga en cuenta que existen diferencias entre C y C ++ en el uso de literales compuestos, solo están disponibles en C.
"abcd" es en realidad un tipo const char[5] , y el lenguaje permite asignarlo a un const char* (y, lamentablemente, un char* aunque C ++ 11 en adelante no lo permite).
int *c = 1; no está permitido por los estándares C ++ o C, ya que no puede asignar un int a un puntero int* (con la excepción de 0 , y en ese caso su intención se expresará más nullptr asignar nullptr lugar).
"abcd" es la dirección que contiene la secuencia de cinco bytes 97 98 99 100 0 - no se puede ver cuál es la dirección en el código fuente, pero el compilador todavía le asignará una dirección.
1 también es una dirección cerca de la parte inferior de su memoria [virtual]. Puede que esto no parezca útil para usted, pero es útil para otras personas , por lo tanto, aunque el "estándar" pueda no permitirlo, cada compilador con el que se encuentre probablemente sea compatible.