2010-01-10 12 views
31

En las siguientes reglas para el caso cuando array decae a puntero:inicializador cadena literal para una matriz de caracteres

Un lvalue [véase la pregunta 2.5] de tipo de matriz-de-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 cadena literal para un array de caracteres.)

¿Cómo entender el caso cuando la matriz es "literal inicializador de cadena para una matriz de caracteres "? Por ejemplo, por favor.

Gracias!

+1

Relacionado: [Excepción a la matriz que no se descompone en un puntero?] (Http://stackoverflow.com/questions/17752978/exception-to-array-not-decaying-into-a-pointer) – legends2k

Respuesta

39

Las tres excepciones donde una matriz no se descompone en un puntero son los 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 la matriz 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) */ 
} 
+1

Me gustó su respuesta mucho mejor antes de todas las ediciones. Conciso y respondió la pregunta. Ahora responde muchas preguntas que ni siquiera se formulan. :-) –

+0

Gracias Prasson. Alguna pregunta: (1) en la Excepción 3, así que aquí lvalue "Hola mundo" es el inicializador literal de cadena de la matriz "a", y por lo tanto "Hola mundo" no decae a un puntero? (2) en la Excepción 2, es "& a" igual que la dirección del primer elemento de la matriz "a"? – Tim

+0

La respuesta es (1) sí, (2) no. Para (2), en la mayoría de las computadoras, si imprime los valores, imprimirán el mismo (no sé de dónde no lo harán). Pero '& a' apunta a toda la matriz, mientras que' & a [0] 'apunta al primer elemento de' a'. Por lo tanto, si imprime '& a + 1' y' & a [0] + 1', serán diferentes incluso cuando '& a' y' & a [0] 'impriman el mismo valor. –

5

Este es un inicializador literal de cadena 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:

Una cadena literal, también llamada una cadena constante, es una secuencia de caracteres sur redondeado por comillas dobles como en "...". Una cadena tiene el tipo `` matriz de caracteres '' y la clase de almacenamiento estática (vea el párrafo A más abajo) y se inicializa con los caracteres dados. Si literales de cadena idénticos son distintos está definido por la implementación, y el comportamiento de un programa que intenta alterar una cadena literal no está definido.

+3

Como menciona Prasoon, estos no son lo mismo –

+0

Gracias, Eli. Entonces en estos ejemplos, ¿cuál es el iniitalizador literal de cadena de qué? ¿Y qué es "Un lvalue de tipo array-of-T" que no se descompone en puntero? – Tim

+0

Respondió una pregunta incorrecta. – cdosborn

7

asumir las declaraciones

char foo[] = "This is a test"; 
char *bar = "This is a test"; 

En ambos casos, el tipo de la cadena literal "This is a test" es "conjunto de 15 elementos de char" . En la mayoría de las circunstancias, las expresiones de matriz se convierten implícitamente de tipo "matriz de elementos N 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 para bar, eso es exactamente lo que sucede.

En la declaración de foo, sin embargo, la expresión está siendo utilizado para inicializar el contenido otra matriz, y por lo tanto es no convertido a un tipo de puntero; en su lugar, el contenido del literal de cadena se copia en foo.

+0

+1 para la respuesta clara y concisa; quizás el único aquí para mostrar que la excepción se trata de la _literal string_ y no la matriz de caracteres a la que está asignada (dado que ambas son matrices de caracteres). – legends2k

+0

'" Esta es una prueba "' como un inicializador de cadena ** es ** una matriz. Como expresión, no se descompone en un puntero sino que permanece como una matriz. Excelente. – cdosborn

Cuestiones relacionadas