2011-10-09 10 views
5

que tiene una estructura que se parece a esto:Dirección de la matriz - diferencia entre tener un símbolo de unión y ningún signo

struct packet { 
    int a; 
    char data[500]; 
}; 
typedef struct packet packet_t; 

Estoy un poco confundido por qué el siguiente código genera la misma dirección para cada printf:

void myfunction() { 
    packet_t packet; 
    printf("%p\n", packet.data); //e.g., outputs 0x7fff1c323c9c 
    printf("%p\n", &packet.data); //e.g., outputs 0x7fff1c323c9c 
} 

¿Alguien tiene una buena explicación para esto?

+0

¿Quiere decir "por qué las dos líneas dan el mismo resultado", o "por qué los resultados son los mismos para cada llamada de función"?Lo primero es fácil (porque los indicadores apuntan a lo mismo), lo último es imposible de decir. –

+2

Si se refiere a una matriz por nombre sin usar corchetes, se enmascara como un puntero al primer elemento. –

+0

posible duplicado de ["Dirección de" (&) una matriz/dirección de ser ignorado gcc?] (Http://stackoverflow.com/questions/2893911/address-of-an-array-address-of-being- ignored-be-gcc) – Caleb

Respuesta

1

No sé por qué esto fue rechazado, es una buena pregunta que expone un comportamiento confuso de C.

La confusión viene porque normalmente cuando se define una matriz se crea un puntero real:

char data[100]; 
printf("%p\n", data); // print a pointer to the first element of data[] 
printf("%p\n", &data); // print a pointer to a pointer to the first element of data[] 

Así que en un sistema típico de escritorio de 32 bits Se asignan 4 bytes para data, que es un puntero a 100 caracteres. Data, el puntero, existe en algún lugar de la memoria.

Cuando crea una matriz en una estructura, no se asigna ningún puntero. En su lugar, el compilador convierte las referencias a packet.data en un puntero en el tiempo de ejecución, pero no asigna ninguna memoria para almacenarlo. Más bien solo usa &packet + offsetof(data).

Personalmente prefiero que la sintaxis sea coherente y requiera un ampersand, con packet.data generando algún tipo de error de tiempo de compilación.

+0

Esta respuesta puede ser incorrecta. Intenté ejecutar el código (gcc 4.8) y tenía exactamente el mismo comportamiento que el código del OP en C y C++; es decir, "& arr" es lo mismo que & (arr [0]) independientemente de si la matriz se declara por separado o como miembro de una estructura. –

4

Esto se debe a que la matriz se desintegra a un puntero que apunta al primer elemento de la secuencia. Por lo tanto, la dirección packet.data es la misma que &packet.data o &packet.data[0].

+3

Sin embargo, los dos son tipos diferentes: el primero es un puntero a una matriz, el último es un puntero a una char. Los dos simplemente están en la misma dirección numérica. –

-2

Porque es lo único razonable que hacer además de hacer que & packet.data cause un error de compilación. Entero a y la matriz de caracteres de datos se disponen secuencialmente en la pila, no hay desreferencia involucrada.

7

En la mayoría de los casos, una expresión que tenga tipo "N-element array of T" se convertirá en una expresión de tipo "puntero a T", y su valor será la dirección del primer elemento en la matriz. Esto es lo que sucede en la primera llamada printf; la expresión packet.data, que tiene el tipo char [500], se reemplaza con una expresión del tipo char *, y su valor es la dirección del primer elemento, por lo que está efectivamente imprimiendo &packet.data[0].

Se produce una excepción a esta regla cuando la expresión de matriz es un operando del operador unitario &; el tipo de la expresión &packet.data es char (*)[500] (apunta a la matriz de 500 elementos de char).

La dirección de una matriz es la misma que la dirección del primer elemento, por lo que ambas llamadas a printf muestran el mismo valor ; es solo que los tipos de expresiones son diferentes. Para ser pedante, ambas expresiones deben ser emitidos a void * en los printf llamadas (el especificador %p conversión espera un argumento void *):

printf("%p\n", (void *) packet.data); 
printf("%p\n", (void *) &packet.data); 
Cuestiones relacionadas