web-dev-qa-db-fra.com

Tableau 2D vs tableau de tableaux

Quelle est la différence entre un tableau 2D et un tableau de tableaux?

J'ai lu des commentaires, tels que @ Dave's , qui semblent différencier les deux.

Cela casse s'il utilise des tableaux 2D, ou des types pointeur à tableau, plutôt qu'un tableau de tableaux. - Dave

J'ai toujours pensé que tous deux faisaient référence à:

int arr_arr[][];

EDIT: @FutureReader, vous voudrez peut-être voir Comment utiliser les tableaux en C++?

11
Mateen Ulhaq

Un tableau à 2 dimensions est par définition, un tableau de tableaux.

Dave disait que dans ce contexte, il existe différentes sémantiques entre la définition d'un tableau 2D comme ceci:

int x[][];

ce:

int *x[];

ou ca:

int **x;
10
Jacob Relkin

Il y a quatre concepts différents ici.

  • Le tableau à deux dimensions: int arr[][]. Il ne peut être redimensionné dans aucune direction et est contigu. L'indexation est la même chose que ((int*)arr)[y*w + x]. Doit être alloué statiquement.
  • Le tableau de pointeur vers: int (*arr)[]. Il ne peut être redimensionné que pour ajouter plus de lignes et est contigu. L'indexation est la même chose que ((int*)arr)[y*w + x]. Doit être alloué dynamiquement, mais peut être libéré free(x);
  • Le pointeur à pointeur: int **arr. Il peut être redimensionné dans n'importe quelle direction et n'est pas nécessairement carré. Habituellement alloué dynamiquement, pas nécessairement contigu, et la libération dépend de sa construction. L'indexation est identique à *(*(arr+y)+x)
  • Le tableau de pointeurs: int *arr[]. Il ne peut être redimensionné que pour ajouter plus de colonnes et n'est pas nécessairement carré. Le redimensionnement et la libération dépendent également de la construction. L'indexation est identique à *(*(arr+y)+x)

Chacun de ceux-ci peut être utilisé arr[y][x], conduisant à la confusion.

22
Dave

La réponse ici est un peu plus subtile.

Un tableau de tableaux est défini comme tel:

int array2[][];

Les types pointeur vers tableau sont définis comme suit:

int (*array2)[];

Les types de tableau de pointeurs sont définis comme suit:

int* array2[];

Le compilateur traite ces deux choses un peu différemment, et il existe une option supplémentaire:

int** array2;

Beaucoup de gens apprennent que ces trois éléments sont identiques, mais si vous en savez plus sur les compilateurs, vous saurez sûrement que la différence est petite, mais c'est là. Beaucoup de programmes fonctionneront si vous en remplacez un, mais au niveau du compilateur et de l'ASM, les choses ne sont PAS identiques. Un manuel sur les compilateurs C devrait fournir une réponse beaucoup plus approfondie.

En outre, si l’implémentation d’un tableau 2D s’intéresse à l’impact, il existe de nombreuses méthodes dont l’efficacité varie en fonction de la situation. Vous pouvez mapper un tableau 2D sur un tableau 1D, ce qui garantit une localisation spatiale lors du traitement de données linéarisées. Vous pouvez utiliser le tableau de tableaux si vous voulez une programmation facile et si vous devez manipuler les lignes/colonnes séparément. Certains types bloqués et autres conceptions sophistiquées sont adaptés au cache, mais vous devez rarement connaître l'implémentation si vous en êtes l'utilisateur.

J'espère que j'ai aidé!

10
foslock

Ce qui suit est un tableau 2D qui peut être appelé un tableau de tableaux:

int AoA[10][10];

Ce qui suit est un pointeur sur un pointeur qui a été configuré pour fonctionner comme un tableau 2D:

int **P2P = malloc(10 * sizeof *P2P);
if(!P2P) exit(1);
for(size_t i = 0; i < 10; i++)
  {
    P2P[i] = malloc(10 * sizeof **P2P);
    if(!P2P[i])
      {
        for(; i > 0; i--)
            free(P2P[i - 1]);
        free(P2P); 
      }
  }

Les deux sont accessibles via AoA[x][y] ou P2P[x][y], mais les deux sont incompatibles. En particulier, P2P = AoA est quelque chose que les débutants s'attendent parfois à travailler, mais ne - P2P ne s'attend pas à pointer vers des pointeurs, mais lorsque AoA se désintègre en un pointeur, il s'agit d'un pointeur vers un tableau , plus précisément int (*)[10], qui le int ** que P2P est censé être.

1
Chris Lutz

Tableau 2d peut inclure ceci:

int x[width * height]; // access: x[x + y * width];

De Wikipedia:

Pour un tableau à deux dimensions, l'élément d'indices i, j aurait Adresse B + c · i + d · j, où les coefficients c et d sont les incréments d'adresse de ligne et de colonne , respectivement.

0
Pubby