Para comprender completamente esto, debe comprender los siguientes conceptos:
¡Las matrices no son punteros!
En primer lugar (y se ha predicado lo suficiente), las matrices no son punteros . En cambio, en la mayoría de los usos, 'decaen' a la dirección de su primer elemento, que puede asignarse a un puntero:
int a[] = {1, 2, 3};
int *p = a; // p now points to a[0]
Supongo que funciona de esta manera para que se pueda acceder al contenido de la matriz sin copiarlos todos. Eso es solo un comportamiento de tipos de matriz y no significa que sean lo mismo.
Matrices multidimensionales
Los arreglos multidimensionales son solo una forma de 'particionar' la memoria de una manera que el compilador / máquina pueda entender y operar.
Por ejemplo, int a[4][3][5]
= una matriz que contiene 4 * 3 * 5 (60) 'trozos' de memoria de tamaño entero.
La ventaja sobre el uso int a[4][3][5]
frente al simple int b[60]
es que ahora están "particionados" (es más fácil trabajar con sus "fragmentos", si es necesario), y el programa ahora puede realizar comprobaciones vinculadas.
De hecho, int a[4][3][5]
se almacena exactamente como int b[60]
en la memoria: la única diferencia es que el programa ahora lo administra como si fueran entidades separadas de ciertos tamaños (específicamente, cuatro grupos de tres grupos de cinco).
Tenga en cuenta: Ambos int a[4][3][5]
y int b[60]
son iguales en memoria, y la única diferencia es cómo los maneja la aplicación / compilador
{
{1, 2, 3, 4, 5}
{6, 7, 8, 9, 10}
{11, 12, 13, 14, 15}
}
{
{16, 17, 18, 19, 20}
{21, 22, 23, 24, 25}
{26, 27, 28, 29, 30}
}
{
{31, 32, 33, 34, 35}
{36, 37, 38, 39, 40}
{41, 42, 43, 44, 45}
}
{
{46, 47, 48, 49, 50}
{51, 52, 53, 54, 55}
{56, 57, 58, 59, 60}
}
A partir de esto, puede ver claramente que cada "partición" es solo una matriz de la que el programa realiza un seguimiento.
Sintaxis
Ahora, las matrices son sintácticamente diferentes de los punteros . Específicamente, esto significa que el compilador / máquina los tratará de manera diferente. Esto puede parecer una obviedad, pero eche un vistazo a esto:
int a[3][3];
printf("%p %p", a, a[0]);
El ejemplo anterior imprime la misma dirección de memoria dos veces, así:
0x7eb5a3b4 0x7eb5a3b4
Sin embargo, solo se puede asignar uno a un puntero de manera tan directa :
int *p1 = a[0]; // RIGHT !
int *p2 = a; // WRONG !
¿Por qué no se a
puede asignar a un puntero pero a[0]
sí?
Esto, simplemente, es una consecuencia de las matrices multidimensionales, y explicaré por qué:
En el nivel de " a
", todavía vemos que tenemos otra "dimensión" que esperar. a[0]
Sin embargo, en el nivel de " ", ya estamos en la dimensión superior, por lo que en lo que respecta al programa, solo estamos viendo una matriz normal.
Puede estar preguntando:
¿Por qué importa si la matriz es multidimensional en lo que respecta a hacer un puntero para ella?
Es mejor pensar de esta manera:
Un 'decaimiento' de una matriz multidimensional no es solo una dirección, sino una dirección con datos de partición (también conocido como aún entiende que sus datos subyacentes están hechos de otras matrices), que consiste en límites establecidos por la matriz más allá de la primera dimensión.
Esta lógica de 'partición' no puede existir dentro de un puntero a menos que la especifiquemos:
int a[4][5][95][8];
int (*p)[5][95][8];
p = a; // p = *a[0] // p = a+0
De lo contrario, se pierde el significado de las propiedades de clasificación de la matriz.
También tenga en cuenta el uso de paréntesis alrededor de *p
: int (*p)[5][95][8]
- Eso es para especificar que estamos haciendo un puntero con estos límites, no una matriz de punteros con estos límites:int *p[5][95][8]
Conclusión
Revisemos:
- Las matrices decaen a direcciones si no tienen otro propósito en el contexto utilizado
- Los arreglos multidimensionales son solo arreglos de arreglos - Por lo tanto, la dirección 'decaída' llevará la carga de "Tengo subdimensiones"
- Los datos de dimensión no pueden existir en un puntero a menos que se los proporcione .
En resumen: los arreglos multidimensionales decaen hacia direcciones que tienen la capacidad de comprender su contenido.