¿Es la matriz 2D un puntero doble? [duplicar]
int main()
{
matrix[2][4] = {{11,22,33,99},{44,55,66,110}};
int **ptr = (int**)matrix;
printf("%d%d",**matrix,*ptr);
}
Pero cuando se pasa una matriz 2-d como parámetro, se encasilla en (*matriz)[2] ... ¿de qué tipo almacena el compilador esta matriz? ¿Se almacena como una matriz 2-d o como un puntero doble? o un puntero a una matriz. Si se almacena como una matriz, ¿cómo se interpreta de manera diferente en diferentes situaciones como la anterior? Por favor ayúdame a entender.
¿Es la matriz 2D un puntero doble?
No. Esta línea de su programa es incorrecta:
int **ptr = (int**)matrix;
Esta respuesta trata sobre el mismo tema.
Si desea una imagen concreta de cómo se implementan las matrices multidimensionales:
Las reglas para las matrices multidimensionales no son diferentes de las de las matrices ordinarias, simplemente sustituya el tipo de matriz "interno" como tipo de elemento. Los elementos de la matriz se almacenan en la memoria directamente uno después del otro:
matrix: 11 22 33 99 44 55 66 110
----------- the first element of matrix
------------ the second element of matrix
Por lo tanto, para abordar el elemento matrix[x][y]
, se toma the base address of matrix + x*4 + y
(4 es el tamaño de la matriz interna).
Cuando las matrices se pasan a funciones, se desintegran y se convierten en punteros a su primer elemento. Como habrás notado, esto sería int (*)[4]
. El 4
tipo luego le indicaría al compilador el tamaño del tipo interno, razón por la cual funciona. Al hacer aritmética de punteros en un puntero similar, el compilador agrega múltiplos del tamaño del elemento, por lo que para matrix_ptr[x][y]
, obtienes matrix_ptr + x*4 + y
, que es exactamente igual que el anterior.
Por tanto, el reparto ptr=(int**)matrix
es incorrecto. Por una vez, *ptr
significaría un valor de puntero almacenado en la dirección de la matriz, pero no hay ninguno. En segundo lugar, no hay un puntero a matrix[1]
ningún lugar de la memoria del programa.
Nota: los cálculos en esta publicación asumen sizeof(int)==1
, para evitar complejidades innecesarias.
No. Una matriz multidimensional es un único bloque de memoria. El tamaño del bloque es el producto de las dimensiones multiplicadas por el tamaño del tipo de elementos, y la indexación en cada par de corchetes se compensa en la matriz por el producto de las dimensiones para las dimensiones restantes. Entonces..
int arr[5][3][2];
es una matriz que contiene 30 int
s. arr[0][0][0]
da el primero, arr[1][0][0]
da el séptimo (compensado en 3 * 2). arr[0][1][0]
da el tercero (compensado en 2).
Los punteros a los que decae la matriz dependerán del nivel; arr
decae a un puntero a una matriz int de 3x2, arr[0]
decae a un puntero a una matriz int de 2 elementos y arr[0][0] decae a un puntero a int.
Sin embargo, también puede tener una matriz de punteros y tratarla como una matriz multidimensional, pero requiere una configuración adicional, porque debe configurar cada puntero en su matriz. Además, se pierde la información sobre los tamaños de las matrices dentro de la matriz ( sizeof
daría el tamaño del puntero). Por otro lado, obtiene la capacidad de tener subarreglos de diferentes tamaños y cambiar hacia dónde apuntan los punteros, lo cual es útil si es necesario cambiar su tamaño o reorganizarlos. Una matriz de punteros como esta se puede indexar como una matriz multidimensional, aunque esté asignada y organizada de manera diferente y sizeof
no siempre se comportará de la misma manera. Un ejemplo asignado estáticamente de esta configuración sería:
int *arr[3];
int aa[2] = { 10, 11 },
ab[2] = { 12, 13 },
ac[2] = { 14, 15 };
arr[0] = aa;
arr[1] = ab;
arr[2] = ac;
Después de lo anterior, arr[1][0]
está 12
. Pero en lugar de proporcionar los bytes int
encontrados 1 * 2 * sizeof(int)
después de la dirección inicial de la matriz arr
, proporciona los bytes int
encontrados 0 * sizeof(int)
después de la dirección señalada por arr[1]
. Además, sizeof(arr[0])
equivale a sizeof(int *)
en lugar de sizeof(int) * 2
.
En C, no hay nada especial que debas saber para comprender las matrices multidimensionales. Funcionan exactamente igual que si nunca se hubieran mencionado específicamente. Todo lo que necesitas saber es que puedes crear una matriz de cualquier tipo, incluida una matriz.
Entonces cuando veas:
matriz int[2][4];
Solo piense, " matrix
es una matriz de 2 cosas; esas cosas son matrices de 4 números enteros". Se aplican todas las reglas normales para matrices. Por ejemplo, matrix
puede descomponerse fácilmente en un puntero a su primer miembro, como cualquier otra matriz, que en este caso es una matriz de cuatro números enteros. (Que, por supuesto, puede descomponerse).
Si puede usar la pila para esos datos (pequeño volumen), entonces normalmente define la matriz:
int matrix[X][Y]
Cuando desea asignarlo en el montón (gran volumen), generalmente define:
int** matrix = NULL;
y luego asigne las dos dimensiones con malloc/calloc. Puede tratar la matriz 2d como int** pero esa no es una buena práctica ya que hace que el código sea menos legible. Aparte de eso
**matrix == matrix[0][0] is true