Como han señalado otros, una matriz multidimensional es una matriz de matrices, no una matriz de punteros.
Creo que la principal causa de malentendidos es el concepto de que cualquier matriz es realmente un puntero.Pero no es estrictamente cierto. Una matriz es una variable que contiene una colección contigua de elementos de un mismo tipo. Entonces, cuando declaras una matriz como int x[2]
, estás declarando una variable que contiene dos enteros. Tenga en cuenta que no contiene ningún puntero.
Ahora la raíz de este malentendido común es que en C/C++ un nombre de matriz evalúa a la dirección de su primer elemento y, por lo tanto, se puede utilizar como un puntero. En otras palabras, cuando escribe x
, significa implícitamente &x
o &x[0]
. Esto probablemente fue hecho para hacer las expresiones más legibles.
Una matriz multidimensional es simplemente una matriz de matrices. En otras palabras, la misma lógica se aplica a ellos, no hay nada especial. Lees la declaración C/C++ comenzando por el nombre y yendo afuera, aplicando modificadores a medida que los encuentras, primero [] y(), luego *, luego escribes, para que interpretes una matriz multidimensional como esta (orden de lectura especificado explícitamente)):
int x [ 2] [ 5];
6. "of type int" 1. "x" 2. "is an array" 3. "of 2". 4. "arrays" 5. "of 5 elements"
lo que no hay tal cosa como matrices multidimensionales en C/C++, pero no hay tal cosa como matriz unidimensional de matrices unidimensionales. De acuerdo con las reglas para matrices unidimensionales, x
, &x
y &x[0]
todas evalúan a la dirección del primer elemento. Pero dado que el primer elemento es una matriz, x[0]
evalúa la dirección de esa matriz, es decir, la dirección de su primer elemento que es una int. Lo mismo ocurre con &x[0]
y &x[0][0]
. Es por eso que el valor de x[0]
es el mismo de su dirección, porque x[0]
es una matriz.
Tenga en cuenta que aunque estas cosas se evalúan en la misma dirección, tienen diferentes tipos. x
es un puntero a una matriz de 5 ints, así como &x[0]
, ya que ambos evalúan la dirección del primer elemento de x. x[0]
evalúa a la dirección del primer elemento de x[0]
, por lo que es un puntero a int, lo mismo ocurre con &x[0][0]
. En este ejemplo se compila bien e imprime la misma dirección para los 4 punteros:
int x[2][5];
int (*y1)[5] = x;
int *y2 = x[0];
int (*y3)[5] = &x[0];
int *y4 = &x[0][0];
printf("%p %p %p %p\n", y1, y2, y3, y4);
Ahora, hay diferentes diseños de memoria para matrices utilizadas en diferentes idiomas. Por ejemplo, para una matriz bidimensional, puede agrupar elementos por filas o columnas. En C/C++, dado que no existen matrices multidimensionales "verdaderas", el diseño de la memoria se define implícitamente mediante las reglas anteriores. Desde int x[2][5]
, que se puede considerar como una matriz bidimensional que tiene 2 filas y 5 columnas, en realidad es una matriz de 2 matrices, cada una de las cuales representa una fila, se obtiene el diseño "grupo por filas", que se presenta en La respuesta de shybovycha.
Tenga en cuenta que también es posible crear una matriz de punteros y utilizarla como una matriz multidimensional. Las diferencias con las matrices multidimensionales "habituales" son:
- Una matriz de punteros contiene punteros en su interior. Es decir, direcciones de los primeros elementos de sub-arrays.
- El diseño de la memoria no es contiguo. Cada subarreglo se puede asignar en cualquier lugar, por ejemplo, utilizando malloc() o nuevo [].
- Las sub-matrices pueden ser de diferentes tamaños.
La ventaja de este enfoque es que se puede utilizar esta matriz como un puntero a puntero (por ejemplo, int **y
), lo que hace que todas las matrices multidimensionales de este tipo compatibles entre sí, incluso si tienen diferentes tamaños.Pero los tamaños deben almacenarse por separado en este caso.
Lea http://c-faq.com/aryptr/index.html –
Le recomendamos que lea [Preguntas frecuentes] (http://stackoverflow.com/questions/4810664/) acerca del uso de matrices en C++;) – fredoverflow