¿Es la matriz 2D un puntero doble? [duplicar]

Resuelto Angus asked hace 13 años • 4 respuestas
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.

Angus avatar Sep 28 '11 23:09 Angus
Aceptado

¿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 4tipo 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**)matrixes incorrecto. Por una vez, *ptrsignificarí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.

jpalecek avatar Sep 28 '2011 16:09 jpalecek

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 ints. 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; arrdecae 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 ( sizeofdarí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 sizeofno 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 intencontrados 1 * 2 * sizeof(int)después de la dirección inicial de la matriz arr, proporciona los bytes intencontrados 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.

Dmitri avatar Sep 28 '2011 19:09 Dmitri

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, " matrixes una matriz de 2 cosas; esas cosas son matrices de 4 números enteros". Se aplican todas las reglas normales para matrices. Por ejemplo, matrixpuede 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).

David Schwartz avatar Sep 28 '2011 17:09 David Schwartz

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
long404 avatar Sep 28 '2011 17:09 long404