Inicializador de cadena literal para una matriz de caracteres

5 minutos de lectura

avatar de usuario
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!

  • Relacionado: ¿Excepción a la matriz que no se descompone en un puntero?

    – leyendas2k

    9 de julio de 2014 a las 8:26

avatar de usuario
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 de a. Entonces, si imprimes &a + 1 y &a[0] + 1será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

avatar de usuario
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 bareso es exactamente lo que sucede.

En la declaración por foosin 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


avatar de usuario
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:

http://c-faq.com/decl/strlitinit.html

¿Ha sido útil esta solución?