2011-07-21 5 views
5

Im bastante confuso que lo que es la diferencia entre estos dos inicializaciones:C Puntero matrices initializtion

int (*p)[10]; 

y

int *p[10] 

Sé que ambos pueden señalar matriz 2D cuyo elemento contar en la fila es 10 ....

+0

Discutido con cierto detalle en la publicación C++ - faq (muchas de las cuales también se aplican a C): http://stackoverflow.com/questions/4810664/how-do-i-use-arrays-in-c – Cubbi

+0

http: // cdecl.org – sidyll

Respuesta

2

Elaborar un poco en las respuestas correctas ya aquí:

La primera línea:

int (*p)[10]; 

declara que "p" es un puntero a la dirección de memoria de una matriz con la capacidad de 10 Ints. Se puede leer en inglés como: "entero-puntero 'p' apunta a 10 entradas secuenciales en la memoria".

La segunda línea:

int *p[10] 

declara que "p []" es una matriz de 10 punteros a enteros. Esta es una matriz de direcciones de memoria que apuntan a enteros. En este caso, "p" es una secuencia de 10 punteros en la memoria (que resultan ser las direcciones de memoria de otras entradas).

+0

¡¡Guay !! Thnx !! tht aclara mis dudas ... – kHAzaDOOm

+1

Para el segundo caso, supongo que quisiste decir '" p "-es- una secuencia de 10 punteros en memoria (que resultan ser las direcciones de memoria de ints) .' –

+0

¡Sí! Perdón por la confusion. – AlexFZ

0

En la primera definición (no inicialización), p es un puntero; en el segundo, p es una matriz de 10 punteros.

+0

puede proporcionar un ejemplo que distinga a ambos .... – kHAzaDOOm

+1

intente 'sizeof p' para ambas definiciones :-) – pmg

4

El primero es un puntero a la matriz, el segundo es una matriz de punteros.

1

En su primer ejemplo, p es un puntero a una matriz de 10 enteros. En el segundo ejemplo, p es una matriz de 10 punteros.

Puede asignar dinámicamente un objeto de tipo "puntero a una matriz de diez int" de la siguiente manera.

int (**ptr)[10] = new (int (*)[10]); 

Nota, no se asigna espacio para ningún ints; solo el puntero mismo

Puede asignar una matriz de 10 enteros de la siguiente manera:

int *ptr = new int[10];

Lo que no se puede hacer (sin conversión explícita) es asignar un puntero a una matriz de asignación dinámica de 10 int a un puntero del tipo int (*)[10]. Siempre que asigne una matriz a través de una nueva, incluso si usa un typedef, el tipo de la nueva expresión es un puntero al primer elemento de la matriz; el tamaño de la matriz no se conserva en el tipo de la nueva expresión.

Esto se debe a que las expresiones new[] pueden asignar matrices donde el tamaño de la matriz se elige en tiempo de ejecución, por lo que no siempre sería posible (o incluso deseable) codificar el tamaño de la matriz en el tipo de la nueva expresión.

Como se ha sugerido, puede asignar dinámicamente una matriz de una matriz de 10 int. El tamaño de la primera matriz se pierde de la información de tipo y lo que se obtiene es un puntero al primer elemento de la matriz (de tamaño 1) de las matrices de cuatro int.

int (*p)[10] = new int[1][10]; 

A pesar de que es una matriz de sólo 1 (arrays de 10 int), que todavía tienen que utilizar delete[] desasignar p.

delete[] p;

Por supuesto, uno nunca debería ser en realidad una posición a tener que llamar a borrar manualmente.

2
int (*p)[10]; 


+------+       +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ 
| p | =========================>|(*p)[0]|(*p)[1]|(*p)[2]|(*p)[3]|(*p)[4]|(*p)[5]|(*p)[6]|(*p)[7]|(*p)[8]|(*p)[9]| 
+------+       +-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+ 

sizeof p volverá sizeof (void *) (4 sobre 32 sistemas de bits, 8 en 64 sistemas de bits)

sizeof *p volverá 10*sizeof (int) (40 en la mayoría de los sistemas)

int *p[10]; is the same as  int* (p[10]); 

p 
+------+------+------+------+------+------+------+------+------+------+ 
| p[0] | p[1] | p[2] | p[3] | p[4] | p[5] | p[6] | p[7] | p[8] | p[9] | 
+------+------+------+------+------+------+------+------+------+------+ 

sizeof p volverá 10*sizeof (void *) (40 en sistemas de 32 bits, 80 en sistemas de 64 bits)

sizeof *p volverá sizeof (int *) (4 sobre 32 sistemas de bits, 8 en 64 sistemas de bits)

+0

Solo quería comentar y felicitarlo por la profundidad y el detalle de esta respuesta. ¡Ve los dibujos ASCII! – AlexFZ

0

Como otros han señalado, int (*p)[10] declara p como un puntero a una matriz de 10 elementos de int, mientras que int *p[10] declara p como un 10- elemento matriz de puntero a int.

En C, las declaraciones se basan en los tipos de expresiones , no en objetos. La idea es que la forma de la declaración debe coincidir con la forma de la expresión tal como se usa en el código.

Supongamos que p es una matriz de punteros a int (el segundo caso). Para acceder a un valor entero en particular, que le subíndice en la matriz y eliminar la referencia al resultado, como en

x = *p[i]; 

operadores de sufijo como [] y () tienen mayor prioridad que los operadores unarios como *, por lo que la afirmación anterior se analiza como *(p[i]) (IOW, * se aplica a la expresión p[i]).

El tipo de la expresión *p[i] es int, por lo que la declaración correspondiente de p es int *p[10];.

Supongamos ahora que p es un puntero a una matriz de int (el primer caso). Para acceder a un valor entero en particular, usted eliminar la referencia al puntero y luego subíndice el resultado, como en

x = (*p)[i]; 

Una vez más, debido a [] tiene mayor precedencia que *, tenemos que utilizar paréntesis para asociar explícitamente la * con sólo p, no p[i]. El tipo de la expresión (*p)[i] es int, por lo que la declaración de p es int (*p)[10];.