通过引用将二维数组传递给函数(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-array
的pointer-to-a-pointer
,而不是pointer-to-a-pointer
。