2010-09-04 3 views
0

Pourquoi la mémoire d'un tableau 2d est-elle accessible par deux paramètres et pas seulement par un (ignorant les pointeurs)? Pourquoi le diagramme de mémoire est-il en termes de lignes et de colonnes? plus pourquoi est-il dit que le tableau 2d est un tableau de tableaux, mais je ne comprends pas cela.2d array confusion

+0

Avez-vous une idée de ce qu'est un tableau 2D? – alternative

+3

Prenez tout le temps dont vous avez besoin pour réfléchir à ce que les deux en deux dimensions pourraient signifier. Vous n'avez pas encore fermé votre question précédente, elle a été répondue. –

Répondre

7

Il s'agit de commodité. Bien sûr, la mémoire est en réalité tout séquentielle, mais parfois on veut pouvoir accéder aux choses avec deux indices (par exemple mettre en œuvre des matrices).

Considérons un réseau 3x3. Il est commode de penser à la mémoire comme ceci:

---------------------------- 
| [0][0] | [0][1] | [0][2] | 
|--------------------------| 
| [1][0] | [1][1] | [1][2] | 
|--------------------------| 
| [2][0] | [2][1] | [2][2] | 
---------------------------- 

Mais en mémoire, il bien sûr ressemble vraiment ceci:

---------------------------------------------------------------------------------- 
| [0][0] | [0][1] | [0][2] | [1][0] | [1][1] | [1][2] | [2][0] | [2][1] | [2][2] | 
---------------------------------------------------------------------------------- 

Nous venons de le diviser en lignes afin que nous puissions comprendre facilement comme en deux dimensions. Nous y accédons avec deux paramètres parce que nous le voulons, parce que c'est pratique pour notre code. Le langage fournit cette implémentation, qui permet d'accéder via deux indices, même si sous les couvertures c'est linéaire et accessible avec un index.

Cette image devrait également vous aider à comprendre pourquoi il peut être considéré comme un tableau de tableaux. Voici une image légèrement modifiée, pour l'emphase:

|||--------------------------|||--------------------------|||--------------------------||| 
||| [0][0] | [0][1] | [0][2] ||| [1][0] | [1][1] | [1][2] ||| [2][0] | [2][1] | [2][2] ||| 
|||--------------------------|||--------------------------|||--------------------------||| 

Comme vous pouvez le voir, il y a vraiment trois tableaux unidimensionnels là. Ainsi, lorsque vous écrivez array[1], vous faites référence à la deuxième composante unidimensionnelle du tableau bidimensionnel complet, c'est-à-dire le deuxième groupe de trois en mémoire. L'ajout d'un second index, array[1][2] prend le troisième élément de ce tableau unidimensionnel, vous descendant à un seul élément du tableau à deux dimensions comme vous le souhaitez.

+1

Magnifiquement mis. –

1

ses tout sur les différences entre:

1 2 3 4 5 6 7 8 9 
[A][A][A][A][A][X][A][A][A] 

et

 1 2 3 4 5 6 7 8 
    1 [A][A][A][A][A][A][A][A] 
    2 [A][A][A][A][A][A][A][A] 
    3 [A][A][A][A][A][A][A][A] 
    4 [A][A][A][A][X][A][A][A] 
    5 [A][A][A][A][A][A][A][A] 
    6 [A][A][A][A][A][A][A][A] 

trouver X dans les données ci-dessus:

dans le premier, afin d'accéder à une adresse que vous avez juste besoin UN index (6 est l'emplacement X)

mais dans le second, vous avez deux index à identi fy une adresse (4: 5 est l'emplacement X).

Vous pouvez considérer la deuxième table comme un tableau du premier tableau.

Notez que l'allocation de mémoire pour ces baies est différente de ce que vous voyez dans mon exemple. Mon échantillon est juste pour mieux comprendre

1

C'est la même raison pour laquelle vous n'écrivez pas une matrice bidimensionnelle comme une série d'entiers dans votre cahier de maths. Cela signifie simplement qu'ils représentent deux caractéristiques différentes. Par exemple les pixels sur l'écran peuvent être représentés comme un seul tableau en utilisant A[i] { i => 0 to N^2 }, mais quand quelqu'un vous demande le 4ème pixel sur la 10ème rangée, vous ne voulez pas faire la multiplication vous-même à chaque fois? Au lieu de cela, vous venez de retourner A[10][4].

0

Les réponses ci-dessus vont bien. Mais ils ne disent que la moitié de l'histoire.Maintenant, je vais vous dire l'autre moitié où vous devez et devez avoir deux variables pour indexer le tableau à deux dimensions. Ceci est lorsque vous déclarez le tableau à deux dimensions sur le tas au lieu de la pile. Une question d'entrevue commune en C est "Comment allez-vous créer dynamiquement un tableau bidimensionnel?".

L'extrait de code est le suivant: -

int **p = (int **)malloc(n * sizeof(int*));

for(int i =0;i < n;i++){

p[i] = (int *)malloc(n * sizeof(int));

}

Dans ce cas, si vous voulez aller à la troisième deuxième élément de colonne de ligne que vous ne pouvez pas faire comme int elem = p[2*n + 1]. simple raison les types sont pas même p [2 * n + 1] est du type int *. Pour obtenir l'élément désiré, vous devez faire p [2] [1].

Et aussi s'il vous plaît ne pas ignorer les commentaires à la question. La notion naturelle de tableau 2D est que tous les éléments à l'intérieur auront besoin de deux redirections pour l'atteindre. L'accès en une seule étape ne fait aucune différence. Il ne peut même pas attacher les choses. Maintenant, si vous pensez que si vous accédez à p [2] [1] est plus lent que d'accéder à p [2 * 20 + 1], vous vous trompez encore . Pourquoi? Parce que le compilateur interne fait la même chose. Au maximum quelques microsecondes du temps de compilation seront sauvegardés. Et savez-vous qui se soucie de sauver quelques microsecondes au moment de la compilation?

Personne.