Passage d’un tableau à deux dimensions à une fonction par référence (programmation C)

J’apprends des pointeurs et je suis bloqué depuis une heure avec ce code,

#include  int determinant(int **mat) /* int mat[3][3] works fine.. int *mat[3] doesn't.. neither does int *mat[] */ { int det; int a=*(*(mat+0)+0); // printf("\n%d",a); int b=*(*(mat+0)+1); // printf("\n%d",b); int c=*(*(mat+0)+2); // printf("\n%d",c); int d=*(*(mat+1)+0); // printf("\n%d",d); int e=*(*(mat+1)+1); // printf("\n%d",e); int f=*(*(mat+1)+2); // printf("\n%d",f); int g=*(*(mat+2)+0); // printf("\n%d",g); int h=*(*(mat+2)+1); // printf("\n%d",h); int i=*(*(mat+2)+2); // printf("\n%d",i); det = a*(e*ih*f) - b*(d*ig*f) + c*(d*he*g); return det; } int main() { int mat[3][3]; int i,j; printf("Enter the 3 X 3 masortingx:\n\n"); for (i=0;i<3;i++) { for (j=0;j<3;j++) { scanf("%d",*(mat+i)+j); } } printf("\nThe determinant of the given 3 X 3 matrix is %d",determinant(mat)); return 0; } 

Je ne pense pas que quelque chose ne va pas avec l’appel de fonction. Peut-être que le problème est en acceptant les arguments. Idk, est-ce que mat n’est pas un pointeur sur un tableau à une dimension, qui serait à nouveau un pointeur sur l’élément de tableau, ce qui en fait un pointeur sur un pointeur? Lorsque j’imprime du texte à certains endroits (juste pour vérifier), j’aperçois que l’exécution va jusqu’après int det dans la fonction et que le programme se bloque à l’étape suivante. mat [3][3] fonctionne bien, mais je veux utiliser certains * là-bas, parce que, comme je l’ai dit, je suis en train d’apprendre.

S’il vous plaît aider! Merci 🙂

Le tableau 2D ne se décompose pas en pointeur en pointeur. Vous pouvez les décomposer en pointeurs de sorte que votre code devrait ressembler à

 int determinant(int *mat) { int det; int a=*((mat+0)+0); // printf("\n%d",a); int b=*((mat+0)+1); // printf("\n%d",b); int c=*((mat+0)+2); // printf("\n%d",c); int d=*((mat+1*3)+0); // printf("\n%d",d); int e=*((mat+1*3)+1); // printf("\n%d",e); int f=*((mat+1*3)+2); // printf("\n%d",f); int g=*((mat+2*3)+0); // printf("\n%d",g); int h=*((mat+2*3)+1); // printf("\n%d",h); int i=*((mat+2*3)+2); // printf("\n%d",i); det = a*(e*ih*f) - b*(d*ig*f) + c*(d*he*g); return det; } 

Le code ci-dessus est juste pour l’illustration, montrant comment le tableau 2-D se désintègre en tableau 1-D.

Lorsque vous essayez d’accéder au tableau à l’aide d’accolades comme a[2][1] le compilateur se déplie alors. En dépliant, je veux dire, la multiplication par sizeof (type) (comme indiqué ci-dessus, multipliez par 3). Donc, si vous tombez en désordre, vous devez le faire vous-même.

Une dernière chose à append, passez toujours la taille de la dimension à la fonction qui doit parcourir le tableau 1-D en 2D. comme

 int determinant(int *mat, int cols, rows); 

Modifier 1:

Juste pour append que @JensGustedt ans est également acceptable si vous souhaitez conserver les tableaux intacts lors d’appels de fonction.

Le bon prototype pour votre fonction est

 int determinant(int mat[][3]); 

ou

 int determinant(int (*mat)[3]); 

(les deux sont équivalents en raison d’une règle spéciale pour les tableaux en tant qu’arguments de fonction)

Ensuite, vous pouvez simplement accéder à vos éléments masortingciels avec quelque chose comme mat[i][j] .

Cela est dû au fait que le tableau à 2 dimensions et le pointeur à pointeur ne sont pas identiques. Peu importe la dimension d’un tableau, sa 1 dimension en mémoire réelle. Nous pouvons donc y accéder en série.

  #include  #include  int determinant(int *masortingx1stMember) { int a, b, c, d, e, f, g, h, i; a = *(masortingx1stMember + 0); b = *(masortingx1stMember + 1); c = *(masortingx1stMember + 2); d = *(masortingx1stMember + 3); e = *(masortingx1stMember + 4); f = *(masortingx1stMember + 5); g = *(masortingx1stMember + 6); h = *(masortingx1stMember + 7); i = *(masortingx1stMember + 8); return ( a*(e*ih*f) - b*(d*ig*f) + c*(d*he*g) ); } int main() { int masortingx[3][3]; // int masortingx[y][x]; not [x][y] int i, j; printf("\nEnter 3x3 Masortingx : "); for(j = 0; j < 3; j++) { for(i = 0; i < 3; i++) { scanf("%d", &matrix[j][i]); } } // call function determinant(int*) using first member of array printf("\nDeterminant = %d", determinant(&matrix[0][0])); getch(); return 0; } 

Si nous devons accéder via ligne et colonne, nous pouvons alors suivre

  data = *(_1stMemberofArray + rowIndex*totalColumn + columnIndex); 

Par exemple,

  data = masortingx[2][1]; 

où type de données de la masortingce est

  int masortingx[3][3]; 

est identique à.

  data = *(masortingxPointer + 2*3 + 1); 

où 3 est le total de la colonne 2 est la rangée (verticale ou y) et 1 est la colonne (horizontale ou x). et le type de données de masortingxPointer est,

  int* masortingxPointer; 

et il devrait pointer sur le premier membre de la masortingce;

La signature correcte pour la fonction serait

 int determinant(int mat[][3]) 

ou

 int determinant(int (*mat)[3]) 

Dans le contexte d’une déclaration de paramètre de fonction, T a[] et T *a sont exactement équivalents.

Quelle que soit l’option choisie, vous pouvez inscrire le mat normalement dans la fonction comme vous le feriez dans le main :

 int a = mat[0][0]; int b = mat[0][1]; ... 

Puisqu’une opération en indice supprime implicitement le pointeur ( a[i] == *(a + i) ), vous n’avez pas à exécuter la danse de déréférencement explicite, ce qui rend votre code plus facile à lire et à comprendre (et potentiellement plus rapide; je Nous avons vu que certains compilateurs génèrent plus d’instructions pour *(*(a + i) + j) que pour a[i][j] , mais ne vous fiez pas à ce que cela soit vrai partout).

Rappelez-vous que lorsqu’une expression de “tableau de N-éléments de T ” apparaît dans la plupart des contextes, elle est convertie en une expression de type “pointeur sur T ” et sa valeur est l’adresse du premier élément du tableau. Comme l’expression dans l’appel à printf est de type “tableau à 3 éléments de tableaux à 3 éléments de int “, elle est remplacée par une expression de type “pointeur sur tableau à 3 éléments de int “.

Si nous passons un tableau multidimensionnel à une fonction:

 int a2[5][7]; func(a2); 

Nous ne pouvons pas déclarer cette fonction comme acceptant un pointer-to-pointer

 func(int **a) /* WRONG */ { ... } 

La fonction finit par recevoir un pointer-to-an-array , pas un pointer-to-a-pointer .