Almacenamiento, semántica y literales de cuerda en la confusión C

He estado leyendo C programación Segunda edición por B & K. En el Apéndice A del libro, donde definen la referencia estándar para C, dicen:

"Una cuerda literal, también llamada constante de cuerda, es una secuencia de caracteres rodeados de citas dobles como en "...". Una cuerda tiene tipo ``array of characters ' ' clase de almacenamiento estática y se inicializa con los caracteres dados."

Esto significa que cualquier secuencia de caracteres entre citas dobles tienen almacenamiento estático.

Ahora, en otra parte del libro, dicen:

"Los arrays de caracteres son un caso especial de inicialización; a cadena se puede utilizar en lugar de la notación de frenos y comas: char pattern[] = "ould"; es un cortocircuito para el largo pero equivalente char pattern[] = { 'o', 'u', 'l', 'd', '\0' };En este caso, el tamaño de la matriz es de cinco (cuatro caracteres más la terminación '\0')."

En la declaración corta, ¿la cadena "debería" tener almacenamiento estático o no? O es Solo una gran variedad de personajes como lo hacen ser.

Algunos lugares más adelante en el libro, también dicen que:

"Hay una diferencia importante entre estas definiciones: char amessage[] = "now is the time"; /* an array */ y char *pmessage = "now is the time"; /* a pointer */amessage es un array, lo suficientemente grande para mantener la secuencia de caracteres y '\0' que inicializa Es. Los caracteres individuales dentro del array pueden ser cambiados pero el amessage siempre se refiere al mismo almacenamiento. Por otro lado, el póster es un puntero, inicializado para apuntar a una constante de cuerda; puntero puede ser modificado posteriormente para apuntar a otro lugar, pero el resultado es indefinido si usted trata de modificar el contenido de la cadena."

Así que, corrígeme si me equivoco, lo que básicamente estoy obteniendo de todo esto es que: Una vez que una secuencia de caracteres encerrados en citas dobles aparecen en un programa, se quedan en memoria y no son destruidos hasta el final del programa. Y también, se almacenan en la memoria como un conjunto de caracteres, como en char pattern[] = { 'o', 'u', 'l', 'd', '\0' }. Y, cuando una cuerda aparece en el lado derecho de un inicialización, como dentro char pattern[] = "ould";, la cadena se copia en la matriz, carácter por carácter en los índices del array, y permanece en memoria hasta el final del programa como una secuencia de caracteres también independientemente de si el patrón[] es destruido o no.

Lo siento si esto es un poco largo pero me ha estado confundiendo, he leído otras respuestas sobre este tema aquí también pero no parecen conectarse bien.

Pregunta hecha hace 3 años, 4 meses, 27 días - Por codecraftsman


3 Respuestas:

  • Una vez que una secuencia de caracteres encerrados en citas dobles aparecen en un programa, se quedan en memoria y no son destruidos hasta el final del programa.

    Más o menos. Lo que no te das cuenta es que char message[] = "foo"; no es una asignación. Es una inicialización.

    Así que cuando tienes:

    int func() {
        char message[] = "foo";
        ...
    

    message es una matriz de caracteres con almacenamiento automático que se inicializa con 4 caracteres. De hecho es azúcar sintáctica para char message[] = {'f', 'o', 'o', '\0'};

    El const estático "foo" puede existir, pero es privado al compilador y depende de la aplicación saber dónde se encuentra si hay. Como programador no tiene acceso a él, ni necesita acceso de todos modos.

    Si desea utilizar el const array estático, debe utilizar un puntero para almacenar su dirección:

    const char *pt = "foo";
    

    El puntero puede ser automático, pero el array apuntado es estático y puede ser devuelto de forma segura de una función.

    Espero no haber añadido a la confusión...

    Respondida el Dec 18, 2020 a las 15:18 - por algorithmadeptc6cb

    Votos positivos: 0 | Votos negativos: 0

  • Entiendo que estás confundido sobre el almacenamiento, semántica y literales de cadena en C. Vamos a clarificar algunos conceptos:

    • Cuerdas literales y almacenamiento estático: Una cadena literal en C (encerrada entre comillas dobles) tiene almacenamiento estático, lo que significa que permanecerá en memoria durante toda la ejecución del programa. Esto se debe a que las cadenas literales se almacenan en la sección de memoria de solo lectura (por lo general) y no se pueden modificar.
    • Declaración de estática: Cuando declaramos una cadena de caracteres estática como en `char pattern[] = "ould";`, en realidad se está creando un array de caracteres estático y se inicializa con los caracteres de la cadena literal. Esta cadena se copia en el array de caracteres estático y permanecerá en memoria durante toda la ejecución del programa.
    • Diferencia entre array y puntero: Es importante tener en cuenta la diferencia entre un array de caracteres y un puntero a caracteres. Cuando declaramos `char amessage[] = "now is the time";`, estamos declarando un array estático de caracteres que se inicializa con la cadena literal. En cambio, `char *pmessage = "now is the time";` declara un puntero a caracteres que apunta a la cadena literal en memoria. El contenido de la cadena literal apuntada por `pmessage` no debe cambiarse, ya que está en una zona de solo lectura.

    En resumen, las cadenas literales en C tienen almacenamiento estático y permanecen en memoria durante toda la ejecución del programa. Cuando se inicializa un array de caracteres con una cadena literal, la cadena se copia en el array y permanece en memoria. Es importante comprender las diferencias entre declarar un array de caracteres y un puntero a caracteres para evitar comportamientos indefinidos en el programa.

    Espero que esta explicación clara tus dudas. Si tienes alguna otra pregunta, no dudes en consultar.

    Respondida el Dec 19, 2020 a las 15:22 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • Almacenamiento de literales de cadena

    Los literales de cadena en C tienen almacenamiento estático, lo que significa que se almacenan en una ubicación fija en la memoria durante toda la ejecución del programa.

    Semántica de las literales de cadena

    Los literales de cadena se inicializan con los caracteres dados y tienen el tipo array of characters. Cuando se utilizan en declaraciones de variables o asignaciones, se crea una copia de la cadena literal en la ubicación de memoria asignada.

    Caso especial para declaraciones de arreglos de caracteres

    En el caso específico de las declaraciones de arreglos de caracteres, se puede utilizar una cadena literal como una forma abreviada de inicializar el arreglo con los caracteres de la cadena. En este caso, el tamaño del arreglo se determina automáticamente según la longitud de la cadena literal más un carácter nulo de terminación ('\0').

    Ejemplo:

    c
    char pattern[] = "ould";
    

    En esta declaración, se crea un arreglo de caracteres llamado pattern con un tamaño de 5 (4 caracteres más el carácter nulo de terminación). La cadena literal "ould" se copia en el arreglo, carácter por carácter, en los índices correspondientes. El arreglo pattern se almacena en la memoria estática y sus valores permanecen sin cambios durante toda la ejecución del programa.

    Diferencia entre arreglos y punteros a cadenas

    Cuando una cadena literal se utiliza en el lado derecho de una asignación a un puntero, como en:

    c
    char pmessage = "now is the time";
    

    Se crea un puntero llamado pmessage que apunta a la cadena literal en la memoria estática. El puntero puede modificarse para apuntar a una ubicación de memoria diferente, pero la cadena literal subyacente permanece sin cambios. En este caso, la cadena literal no se almacena en el arreglo apuntado por pmessage, sino que se almacena por separado en la memoria estática.

    Conclusión*

    Los literales de cadena en C tienen almacenamiento estático y se almacenan en la memoria como una secuencia de caracteres. Cuando se utilizan en declaraciones de variables o asignaciones, se crea una copia de la cadena literal en la ubicación de memoria asignada. En el caso de las declaraciones de arreglos de caracteres, se puede utilizar una cadena literal como una forma abreviada de inicializar el arreglo con los caracteres de la cadena. Las cadenas literales no se destruyen hasta el final del programa, independientemente de si las variables o arreglos que las referencian se destruyen.

    Respondida el Dec 19, 2020 a las 15:33 - por Gemini

    Votos positivos: 0 | Votos negativos: 0