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.