Tim
En las siguientes reglas para el caso en que la matriz se descompone en un puntero:
Un valor [see question 2.5] de tipo array-of-T que aparece en una expresión decae (con tres excepciones) en un puntero a su primer elemento; el tipo del puntero resultante es puntero a T.
(Las excepciones son cuando la matriz es el operando de un operador sizeof o &, o es un inicializador de cadena literal para una matriz de caracteres).
¿Cómo entender el caso cuando la matriz es “inicializador de cadena literal para una matriz de caracteres”? Algún ejemplo por favor.
¡Gracias!
Prasoon Saurav
Las tres excepciones en las que una matriz no se convierte en un puntero son las siguientes:
Excepción 1. — Cuando la matriz es el operando de sizeof
.
int main()
{
int a[10];
printf("%zu", sizeof(a)); /* prints 10 * sizeof(int) */
int* p = a;
printf("%zu", sizeof(p)); /* prints sizeof(int*) */
}
Excepción 2. — Cuando el arreglo es el operando del &
operador.
int main()
{
int a[10];
printf("%p", (void*)(&a)); /* prints the array's address */
int* p = a;
printf("%p", (void*)(&p)); /*prints the pointer's address */
}
Excepción 3. — Cuando la matriz se inicializa con una cadena literal.
int main()
{
char a[] = "Hello world"; /* the literal string is copied into a local array which is destroyed after that array goes out of scope */
char* p = "Hello world"; /* the literal string is copied in the read-only section of memory (any attempt to modify it is an undefined behavior) */
}
-
Me gustó mucho más tu respuesta antes de todas las ediciones. Conciso y respondió a la pregunta. Ahora responde muchas preguntas que ni siquiera se hacen. 🙂
– Alok Singhal
10 de enero de 2010 a las 4:58
-
Gracias Prason. Algunas preguntas: (1) en la Excepción 3, ¿así que aquí lvalue “Hola mundo” es el inicializador literal de cadena de la matriz de caracteres “a” y, por lo tanto, “Hola mundo” no se convierte en un puntero? (2) en la Excepción 2, ¿es “&a” igual que la dirección del primer elemento de la matriz “a”?
– Tim
10 de enero de 2010 a las 5:03
-
La respuesta es (1) sí, (2) no. Para (2), en la mayoría de las computadoras, si imprime los valores, imprimirán lo mismo (no sé de ninguna en la que no lo hagan). Pero
&a
apunta a toda la matriz mientras que&a[0]
apunta al primer elemento dea
. Entonces, si imprimes&a + 1
y&a[0] + 1
serán diferentes incluso cuando&a
y&a[0]
imprimir el mismo valor.– Alok Singhal
10 de enero de 2010 a las 5:09
-
Sí, el valor de &a es el mismo que el valor de la dirección del primer elemento de la matriz ‘a’, pero sus tipos son diferentes.
– Prasoon Saurav
10 de enero de 2010 a las 5:11
-
Gracias Alok. Creo que un literal de agitación es un valor r y no un valor l, ya que es el valor de algún almacenamiento en la memoria de solo lectura, no el almacenamiento en sí mismo y no puede aparecer en el lado izquierdo de =. Si me equivoco, ¿cualquier literal además del literal de cadena también puede ser lvalue? Entonces, ¿qué significa lvalue y qué hace que un lvalue sea diferente de un rvalue?
– Tim
10 de enero de 2010 a las 5:18
Juan Bode
Asumir las declaraciones
char foo[] = "This is a test";
char *bar = "This is a test";
En ambos casos, el tipo del literal de cadena “This is a test
” es “matriz de 15 elementos de char”. En la mayoría de las circunstancias, las expresiones de matriz se convierten implícitamente del tipo “matriz de N elementos de T” a “puntero a T”, y la expresión se evalúa como la dirección del primer elemento de la matriz En la declaración de bar
eso es exactamente lo que sucede.
En la declaración por foo
sin embargo, la expresión se está utilizando para inicializar el contenido de otra matriz y, por lo tanto, es no convertido a un tipo de puntero; en cambio, el contenido del literal de cadena se copian en foo
.
-
+1 por la respuesta clara y concisa; quizás el único aquí para mostrar que la excepción es sobre el cadena literal y no la matriz de caracteres a la que está asignada (dado que ambas son matrices de caracteres).
– leyendas2k
9 de julio de 2014 a las 8:36
-
"This is a test"
como un inicializador de cadena es una matriz. Como expresión, no se convierte en un puntero, sino que sigue siendo una matriz. Excelente.– cdosborn
21 de junio de 2015 a las 4:47
Eli Bendersky
Este es un inicializador de cadena literal para una matriz de caracteres:
char arr[] = "literal string initializer";
También podría ser:
char* str = "literal string initializer";
Definición de K&R2:
Un literal de cadena, también llamado constante de cadena, es una secuencia de caracteres entre comillas dobles como en “…”. Una cadena tiene el tipo “arreglo de caracteres” y la clase de almacenamiento estático (ver Par.A.3 a continuación) y se inicializa con los caracteres dados. Si los literales de cadena idénticos son distintos está definido por la implementación, y el comportamiento de un programa que intenta alterar un literal de cadena no está definido.
-
Como menciona Prasoon, no son lo mismo
– Blue Raja – Danny Pflughoeft
10 de enero de 2010 a las 4:58
-
Gracias, Eli. Entonces, en estos ejemplos, ¿cuál es el inicializador literal de cadena de qué? ¿Y qué es “Un valor l de tipo matriz de T” que no se descompone en un puntero?
– Tim
10 de enero de 2010 a las 5:07
Parece que extrajiste esa cita de las preguntas frecuentes de comp.lang.c (tal vez una versión anterior o tal vez la versión impresa; no coincide con el estado actual de la versión en línea):
http://c-faq.com/aryptr/aryptrechev.html
La sección correspondiente enlaza con otras secciones de las Preguntas frecuentes para profundizar en esas excepciones. En tu caso, deberías fijarte en:
Relacionado: ¿Excepción a la matriz que no se descompone en un puntero?
– leyendas2k
9 de julio de 2014 a las 8:26