web-dev-qa-db-fra.com

Décomposition des tableaux multidimensionnels en tant que paramètres de fonction

Je sais que par exemple ceci:

void foo(int a[])// or a[x]

sera considéré par le compilateur comme ceci:

void foo(int *a)

Mais je ne sais pas, et je n'ai trouvé nulle part comment le compilateur voit les tableaux multidimensionnels

Par exemple:

void foo(int a[3][4])

Sera-ce quelque chose comme ça?

void foo(int (*a)[4])

Ou quelque chose comme ça?

void foo(int **a)
16
Leon Trotsky

Lorsqu'un tableau se décompose, il se transforme en un pointeur sur le premier élément. Dans le cas de int a[3][4], a est un tableau de int[4], ainsi un pointeur sur un élément de int [3][4] a le type int (*)[4].

Donc ça:

void foo(int a[3][4])

Est le même que:

void foo(int (*a)[4])
21
dbush

Le compilateur ne peut pas indexer un tableau multi-dimensionnel passé pour fonctionner correctement sans connaître toutes les dimensions sauf la plus externe.

Donc, pour un tableau 1D, aucune longueur n'est requise:

void foo(int a[]);

et 

void foo(int a[3]);

sont égaux bien que trompeurs, parce que C ne fait pas attention à la longueur d’un tableau: c’est au programmeur de bien faire les choses.

Pour un tableau 2D, la dimension interne do doit être correcte, sinon le compilateur ne saura pas l'indexer. Alors

void foo(int a[][3]);

c'est bien, mais

void foo(int a[][]);

ne peut pas être codé, et 

void foo(int a[42][3]);

est bon mais inutile, et pas restrictif, puisque tous les besoins du compilateur sont les informations sur comment pour indexer, et non combien .

5
Weather Vane
void foo(int a[3][4])

a est un tableau de longueur 3, constitué de tableaux int de 4 éléments.

Voici comment cela se présente:

+---+---+---+---+
| 0 | 1 | 2 | 3 |
+---+---+---+---+
| 0 | 1 | 2 | 3 |
+---+---+---+---+
| 0 | 1 | 2 | 3 |
+---+---+---+---+

Vous pouvez ajouter des lignes, mais vous ne pouvez pas ajouter de colonnes, car l'accès à l'élément d'un k[3][4] se fait comme a[3][2] = a[3*4 + 2]. Voici comment trouver une boîte du diagramme ci-dessus en utilisant la connaissance des lignes et des colonnes. L'équation a[b][c] = a[b * row_number + c] ne tient pas lorsque la matrice est non carrée. Dire,

+---+---+---+---+---+
| 0 | 1 | 2 | 3 | 4 |
+---+---+---+---+---+
| 0 | 1 | 2 | 3 |
+---+---+---+---+

Est ce que tu comprends ça?

Regardez le premier tableau ci-dessus. Il pourrait être énuméré d'une manière différente. Que diriez-vous:

+---+---+----+----+
| 0 | 1 | 2  | 3  |
+---+---+----+----+
| 4 | 5 | 6  | 7  |
+---+---+----+----+
| 8 | 9 | 10 | 11 |
+---+---+----+----+

en fait (parce que c'est un tableau, pas une table)

+---+---+---+---+---+---+---+---+---+---+----+----+
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
+---+---+---+---+---+---+---+---+---+---+----+----+

Voir, en C, un tableau 2D est un tableau unidimensionnel, juste avec des indices différents. Donc, cela pourrait être écrit comme:

void foo(int a[])

ou

void foo(int *a)

Qu'en est-il de

void foo(int **a)

C'est un tableau de références aux tableaux int. Ce n'est pas un tableau 2D. Au contraire, il peut être utile rarement. Par exemple, lorsque vous voulez avoir un tableau 2D, les tableaux intérieurs (lignes) ont des longueurs différentes. De plus, c'est la façon dont Java gère les tableaux 2D.

1
MCCCS

Les tableaux multidimensionnels sont souvent une source de problèmes, en particulier si vous souhaitez autoriser une taille dynamique.

Dans le cas général, je suggérerais d'utiliser

void foo(int* a, int size1, int size2);

ou

void foo(int* a, int numSizes, int* sizes);

Passer explicitement la taille limite les segfaults très courants que vous obtiendriez à cause de la décroissance du pointeur et du manque de vérification. L'utilisation de types de tableaux est très fragile et n'est pas recommandée dans la plupart des cas.

Vous pouvez aussi vouloir spécifier la méthode d’indexation, généralement a[size1*i+j] mais vous voudrez peut-être autre chose.

1
meneldal