通过引用将二维数组传递给函数(C编程)

我正在学习指针,现在卡住了一个小时,用这段代码,

#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 matrix:\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; } 

我认为函数调用没有任何问题。 也许问题在于接受论点。 Idk,是不是指向一维数组的指针,它又是一个指向数组元素的指针,使mat成为指针的指针? 当我在某些地方打印一些文本(只是为了检查)时,我发现执行一直持续到函数中的int det之后,程序在下一步中崩溃。 mat [3][3]运作良好,但我想在那里使用一些* ,因为正如我所说,我正在’学习’..

请帮忙! 谢谢 :)

2D数组不会衰减到指针指针。 您可以将它们衰减为指针,以便您的代码看起来像

 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; } 

上面的代码仅用于说明,展示了二维arrays如何衰减为一维arrays。

当你尝试使用像a[2][1]这样a[2][1]大括号访问数组时,编译器会为你展开。 通过展开我的意思是乘以sizeof(类型)(如上所示乘以3)。 因此,如果你腐烂到1-D,你必须自己做。

还有一件事要添加,总是将尺寸的大小传递给必须将1-Darrays作为2-D的function。 喜欢

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

编辑1:

只是要添加@JensGustedt ans也可以,如果你想在函数调用中保持数组完整。

你的function正确的原型是

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

要么

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

(两者都是等价的,因为数组作为函数参数的特殊规则)

然后你可以使用像mat[i][j]这样的东西来访问你的矩阵元素。

这是因为二维数组和指针指针不相同。 无论数组有多少维度,它在实际内存中都是1维。 所以我们可以连续访问它。

  #include  #include  int determinant(int *matrix1stMember) { int a, b, c, d, e, f, g, h, i; a = *(matrix1stMember + 0); b = *(matrix1stMember + 1); c = *(matrix1stMember + 2); d = *(matrix1stMember + 3); e = *(matrix1stMember + 4); f = *(matrix1stMember + 5); g = *(matrix1stMember + 6); h = *(matrix1stMember + 7); i = *(matrix1stMember + 8); return ( a*(e*ih*f) - b*(d*ig*f) + c*(d*he*g) ); } int main() { int matrix[3][3]; // int matrix[y][x]; not [x][y] int i, j; printf("\nEnter 3x3 Matrix : "); 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; } 

如果我们必须通过行和列访问,那么我们可以执行以下操作

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

例如,

  data = matrix[2][1]; 

矩阵的数据类型是什么

  int matrix[3][3]; 

是完全相同的。

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

其中3是总列2是行(垂直或y),1是列(水平或x)。 和matrixPointer的数据类型是,

  int* matrixPointer; 

它应该指向矩阵的第一个成员;

函数的正确签名是

 int determinant(int mat[][3]) 

要么

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

在函数参数声明的上下文中, T a[]T *a完全等效。

使用任一选项,您可以在函数中正常下标mat ,就像在main

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

由于下标操作隐式取消引用指针( a[i] == *(a + i) ),因此您不必进行显式取消引用,使您的代码更易于阅读和理解(并且可能更快;我’已经看到一些编译器为*(*(a + i) + j)a[i][j]更多的指令,但不依赖于它在任何地方都是真的。

请记住,当在大多数上下文中出现“N元素数组T ”的表达式时,它将转换为“指向T指针”类型的表达式,其值是数组中第一个元素的地址。 由于对printf的调用中的表达式mat具有“3元素数组int元素的3元素数组”,因此将其替换为“指向3元素数组的int ”类型的表达式。

如果我们将多维数组传递给函数:

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

我们不能将该函数声明为接受pointer-to-pointer

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

该函数最终接收到pointer-to-an-arraypointer-to-a-pointer ,而不是pointer-to-a-pointer