C ++, tableau multidimensionnel

Lorsqu’un tableau multidimensionnel est passé à une fonction, pourquoi le C ++ exige-t-il que la spécification spécifie uniquement la première dimension

Une meilleure façon de demander ceci est de demander pourquoi C ++ ne nécessite pas de spécifier la première dimension.

La raison en est que pour tous les tableaux, vous ne pouvez pas passer de tableaux par valeur à une fonction. Si vous essayez de déclarer une fonction prenant un tableau, le compilateur ajustera la déclaration au type de pointeur correspondant.

Cela signifie que la dimension que vous spécifiez n’a pas d’importance, car elle ne fait pas partie de la signature de la fonction.

Par exemple, ils déclarent tous exactement la même fonction.

void f(int *p); void f(int p[]); void f(int p[10]); void f(int p[100]); 

Lors de la navigation dans le tableau désigné par p dans la fonction, le copmiler a uniquement besoin d’informations sur la taille des éléments du tableau, autrement dit sizeof(int) .

Pour les tableaux plus complexes, exactement la même chose. Ce sont tous les mêmes:

 void g(Type p[][10][20]); void g(Type (*p)[10][20]); void g(Type p[10][10][20]); void g(Type p[99][10][20]); 

Mais ce sont tous différents de:

 void g(Type p[][5][20]); 

Parce que l’ajustement de la dimension de tout élément autre que la dimension du tableau externe affecte la taille (au moins) des éléments du tableau externe, ce qui signifie que l’arithmétique du pointeur pour naviguer dans le tableau doit être modifiée.

Par exemple, int a[n][m] est un tableau dont le type est un tableau int de longueur m . En d’autres termes, la longueur du tableau fait partie de son type. Et comme pour tous les parameters de fonction, le compilateur doit connaître son type.

Un tableau multidimensionnel n’existe pas en c ++. C’est juste une syntaxe qui lui ressemble. Dans int a[4] et int b[5] a et b sont de types différents.

Si vous vous référez à l’allocation statique, c’est simple. Parce que les blocs de mémoire sont contigus, les cellules de mémoire se suivent et le compilateur sait où se trouve la cellule suivante.

Pour un tableau unidimensionnel en mémoire ressemble à ceci:

http://soffr.miximages.com/arrays/arrays3.gif

Pour un tableau bidimensionnel en mémoire ressemble à ceci:

http://soffr.miximages.com/arrays/IC506192.png

En bref: le compilateur n’a pas besoin de la dimension, car un tableau se décompose en un pointeur. Mais le compilateur a besoin de toute dimension supplémentaire pour calculer le bon emplacement en mémoire.

Au début, vous devez savoir qu’un tableau en C / C ++ est un object continu linéaire en mémoire. Ce qui est très efficace.

Dans la mesure où un tableau en C / C ++ est un object continu linéaire en mémoire, un tableau se décompose en un pointeur. Copier le tableau complet sera une perte de temps et de mémoire et n’est pas requirejs. Un pointeur est tout ce qui est nécessaire pour parcourir le tableau. Pour parcourir le tableau, vous pouvez utiliser l’opérateur d’incrémentation ou tout calcul qui donne une adresse valide dans le tableau. Vous pouvez définir un délimiteur dans le tableau lui-même, par exemple ‘\ 0’ dans une chaîne, ou transmettre la longueur à la fonction seperatley pour indiquer à votre code l’emplacement de la fin du tableau.

Avec les tableaux multidimensionnels, la chose est un peu plus compliquée. Un tableau multi-dimensionnel n’est toujours qu’un object continu linéaire dans la mémoire! Mais le compilateur a besoin des informations sur les dimensions supplémentaires à calculer pour corriger la position en mémoire, imaginez ce qui suit:

 char array[10][10]; // 0 - 99 

correct:

 // formal argument tells your comstackr, that each column is 10 elements long funca(int array[10][10]) { // access to element 25 (2 * 10 + 4, the 10 is known through your formal argument, remember that an array is null based) array[2][3] = 'x'; } 

faux:

 // formal argument tells your comstackr, that ech colum is 5 elements long funcb(int array[10][5]) { // access to element 15 (2 * 5 * + 4, the 5 is known through your formal argument, remember that an array is null based) array[2][3] = 'x'; } 

Une remarque (ou un avertissement): Les tableaux en Java, notamment les tableaux multidimensionnels (irréguliers), sont complètement différents.