multidimensional length bidimensional array c arrays multidimensional-array jagged-arrays ansi-c

length - Arrays multidimensionales en C: ¿son irregulares?



dynamic array c++ (6)

Esto dependería.

Las matrices multidimensionales en C están organizadas de forma secuencial.

Puede crear matrices dentadas si quiere usar punteros.

Una simple pregunta sobre el lenguaje de programación C (ANSI-C):

¿Las matrices multidimensionales en C son dentadas?

Quiero decir, ¿estamos hablando de "matriz de matrices" (una matriz de punteros a otras direcciones en la memoria), o esto es simplemente "matriz unidimensional larga" (que se almacena secuencialmente en la memoria)?

Lo que me molesta es que estoy algo seguro de que:

matrix[i][j] es equivalente a * ( * (matrix + i) + j)


Si declaras una matriz multidimensional, obtienes una "matriz unidimensional larga" (que se almacena secuencialmente en la memoria).

Si declara un puntero a puntero (a puntero ....) obtiene matrices de matrices.

Esta diferencia es fuente de mucha confusión para los programadores principiantes C.


Tienes razón, esa matrix[i][j] es equivalente a *(*(matrix + i) + j) , ya que arr[i] es equivalente a *(arr + i) . Sin embargo, tenga en cuenta que si arr está declarado como

int arr[64];

entonces cualquier referencia a arr puede convertirse implícitamente en &arr[0] , que es un puntero al primer elemento. Lo mismo sucede con las matrices de matrices:

int matrix[8][8];

Aquí la matrix tiene el tipo int[8][8] , que se convierte automáticamente en int (*)[8] cuando se le agrega un entero, como en matrix + i . Entonces *(matrix + i) tiene tipo int[8] , que se convierte nuevamente a int * cuando se agrega j , entonces *(matrix + i) + j tiene tipo int * , por lo tanto *(*(matrix + i) + j) tiene tipo int como se esperaba.

Entonces, el punto es que las matrices no son punteros , sino que se pueden convertir implícitamente en un puntero a su primer elemento.

Entonces, si asigna matrices de matrices como las anteriores ( int matrix[8][8]; ), entonces todos los elementos son consecutivos en la memoria.


Una matriz multidimensional en C es contigua. El seguimiento:

int m[4][5];

consiste en 4 int[5] s dispuestos uno al lado del otro en la memoria.

Una variedad de punteros:

int *m[4];

es irregular Cada puntero puede señalar (el primer elemento de) una matriz separada de una longitud diferente.

m[i][j] es equivalente a *(*(m+i)+j) . Ver el estándar C11 , sección 6.5.2.1:

La definición del operador de subíndice [] es que E1 [E2] es idéntico a (* ((E1) + (E2)))

Por lo tanto, m[i][j] es equivalente a (*(m+i))[j] , que es equivalente a *(*(m+i)+j) .

Esta equivalencia existe porque en la mayoría de los contextos, las expresiones del tipo de matriz decaen a los punteros a su primer elemento (estándar C11, 6.3.2.1). m[i][j] se interpreta de la siguiente manera:

  • m es una matriz de matrices, por lo que se desintegra a un puntero a m[0] , la primera subcadena.
  • m+i es un puntero al i th subcampo de m .
  • m[i] es equivalente a *(m+i) , desreferenciando un puntero al i subcampo de m . Como esta es una expresión del tipo de matriz, se desintegra a un puntero a m[i][0] .
  • m[i][j] es equivalente a *(*(m+i)+j) , desreferenciando un puntero al j ésimo elemento del i ésimo subconjunto de m .

Tenga en cuenta que los punteros a las matrices son diferentes de los punteros a su primer elemento. m+i es un puntero a una matriz; no es una expresión del tipo de matriz, y no decae, ya sea a un puntero a un puntero oa cualquier otro tipo.


Una matriz o matrices, como la int matrix[A][B] no es irregular, ya que cada elemento de la matrix es una array of B int .

Desea saber que el resultado de *(*(matrix+i)+j) es y compárelo con el resultado de la matrix[i][j] .

Dado que el tipo de matrix es una array of A array of B int , entonces la expresión matrix+i es un puntero que apunta a la i ésima array of B int de la matrix , y su tipo es int (*)[B] . La desreferenciación de esta expresión da como resultado una array of B int . La expresión *(matrix+i)+j) da como resultado un puntero al j th int de esa matriz. La desreferenciación de esa expresión da como resultado un int . Esto es equivalente a lo que haría la expresión matrix[i][j] .

Una matriz de punteros, como int *matrix[A] , puede ser irregular, ya que cada elemento de la matrix puede apuntar a una asignación de tamaño diferente.


Un área de memoria consecutiva:

int arr[N][M];

Un área de memoria no consecutiva:

int** arr = malloc(N*sizeof(int*)); for (int i=0; i<N; i++) arr[i] = malloc(M*sizeof(int));

Puede usar arr como una matriz bidimensional (por ejemplo, arr[1][2] = 3 ) en ambos casos. Pero puede aplicar con seguridad operaciones de copia más grandes, como memset(arr,0,N*M*sizeof(int)) , solo en el primer caso.