Renvoyer un tableau 2D ou un pointeur à un

Si un tableau 2d est créé, int 2DRepresentation[mapWidth][mapHeight]; dans une fonction, quel est le meilleur moyen de retourner ceci?

à quoi ressemble la fonction retournée?

Serait-il préférable de créer un pointeur sur un tableau 2D et de le transmettre à une fonction, en le modifiant dans la fonction? Si tel est le cas, à quoi ressemble un pointeur sur un tableau 2D? Comme ça:

int *2DRepresentation[mapWidth][mapHeight]; ?

Comment le paramètre de fonction ressemblerait-il à celui qui accepte un pointeur de tableau 2D?

Vous devrez renvoyer l’adresse de base du tableau, c’est-à-dire un Pointer . Cependant, la seule solution est de rendre le tableau static sinon une fois que la fonction sera hors de scope, elle sera détruite. Si vous ne voulez pas le rendre static vous devez utiliser dynamic memory allocation .

Exemple de pseudo-code:

  int **array; // array is a pointer-to-pointer-to-int array = malloc(mapHeight * sizeof(int *)); if(array == NULL) { fprintf(stderr, "out of memory\n"); exit or return } for(i = 0; i < mapHeight ; i++) { array[i] = malloc(mapWidth * sizeof(int)); if(array[i] == NULL) { fprintf(stderr, "out of memory\n"); exit or return } } 

Voici comment vous pourriez le transmettre à une fonction nommée foo say:

 foo(int **array, int _mapHeight, int _mapWidth) { } 

Les tableaux se décomposent en pointeurs. Par conséquent, vous devez transmettre les valeurs des lignes et des colonnes sous forme d'arguments distincts.

Si un tableau 2d est créé “int 2DRepresentation [mapWidth] [mapHeight];” dans une fonction, quel est le meilleur moyen de retourner ceci?

Si elle est créée dans une fonction telle que vous l’avez représentée (en supposant que mapWidth, mapHeight sont des constantes), elle ne devrait pas être renvoyée. Parce qu’il réside sur la stack et qu’il sort de la scope lors du retour de la fonction, sa référence ne fait que pointer vers le garbage.


Serait-il préférable de créer un pointeur sur un tableau 2D et de le transmettre à une fonction, en le modifiant dans la fonction?

Oui vous avez raison.

à quoi ressemblerait le paramètre de fonction qui accepte un pointeur de tableau 2D?

Exemple:

 void foo( int twoDimensionalArray [][3] ) { // Now you can modify the array received. } int main() { int ar[3][3] ; foo(ar) ; // ..... } 

Ou vous pouvez allouer dynamicment de la mémoire dans side foo et en renvoyer une référence.

 int** foo() { // .... return mallocatedTwoDimensionalArray ; } 

Pour que le tableau rest en mémoire, il doit soit être déclaré static soit alloué explicitement à l’aide de malloc ou calloc (chaque solution a des implications en calloc . En d’autres calloc la version static sera écrasée lors du prochain appel de la fonction. la version allouée doit être explicitement libérée ultérieurement pour éviter les memory leaks).

Notez que les pointeurs et les tableaux ne sont pas la même chose en C, et puisque vous avez affaire à une allocation dynamic dans le cas malloc , vous travaillerez avec des pointeurs. Le référencement des éléments de tableau à l’aide de ces pointeurs sera fonctionnellement identique à celui des éléments de tableau; vous ne devriez donc pas remarquer de différence une fois le tableau créé.

Voici un exemple qui alloue, remplit et retourne un tableau 2D utilisant un seul malloc (à des fins d’efficacité et pour permettre l’utilisation d’un seul free pour la désallocation):

 int **get2dArray(int rows, int cols) { int **array2d; int i, j, offset; int *gridstart; offset = rows * sizeof(int *); array2d = malloc( offset + rows*cols*sizeof(int) ); /* Demote to char for safe pointer arithmetic */ gridstart = (int *)((char *)array2d + offset); for ( i = 0; i < rows; i++ ) { /* Point to the proper row */ array2d[i] = gridstart + i*cols; /* Populate the array -- your code goes here */ for ( j = 0; j < cols; j++ ) { array2d[i][j] = i*cols + j; } } return array2d; } int main ( int argc, char **argv ) { int **testarray; testarray = get2dArray( 10, 100 ); /* Verify that addressing and population went as planned */ printf( "%d %d %d %d %d %d\n", testarray[0][0], testarray[2][55], testarray[4][98], testarray[5][0], testarray[7][15], testarray[9][99] ); free(testarray); return 0; } 

Il existe de nombreuses autres façons de procéder, mais cela illustre une fonction qui renverra un pointeur "tableau" 2D.

Il est préférable de définir le tableau en dehors de la fonction et de le transmettre.

Rappelez-vous qu’un tableau, lorsqu’il est utilisé comme argument de fonction, se décompose en un pointeur sur son premier élément et est donc un pointeur dans la fonction. Vous devez aussi passer la taille.
Si vous avez un compilateur C99, vous pouvez utiliser un “paramètre modifié de manière variable” (voir 6.7.5.3):

 int func(int rows, int cols, int data[rows][cols]) { int sum = 0; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { sum += data[row][col]; } } return sum; } 

et appelez-le avec, par exemple:

 int main(void) { int a[42][100] = {0}; if (func(42, 100, a) == 0) /*ok*/; int b[1000][2] = {0}; if (func(1000, 2, b) == 0) /*ok*/; }