我正在学习指针,现在已经卡住了一个小时,使用此代码,
#include <stdio.h>
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*i-h*f) - b*(d*i-g*f) + c*(d*h-e*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
指向一维数组的指针,它又是一个指向数组元素的指针,使mat
成为指针的指针?
当我在某些地方打印一些文本(只是为了检查)时,我发现执行一直持续到函数中的int det
之后,程序在下一步中崩溃。
mat [3][3]
运作良好,但我想在那里使用一些*
,因为正如我所说,我正在'学习'..
请帮忙! 谢谢:))
答案 0 :(得分:6)
您的功能的正确原型是
int determinant(int mat[][3]);
或
int determinant(int (*mat)[3]);
(两者都是等价的,因为数组作为函数参数的特殊规则)
然后,您只需使用mat[i][j]
。
答案 1 :(得分:3)
这是因为二维数组和指针指针不相同。 无论数组有多少维度,它在实际内存中都是1维。所以我们可以连续访问它。
#include <stdio.h>
#include <conio.h>
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*i-h*f) - b*(d*i-g*f) + c*(d*h-e*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;
它应该指向矩阵的第一个成员;
答案 2 :(得分:1)
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*i-h*f) - b*(d*i-g*f) + c*(d*h-e*g);
return det;
}
上面的代码仅用于说明,展示了二维阵列如何衰减为一维阵列。
当您尝试使用a[2][1]
等大括号访问数组时,编译器会为您展开。通过展开我的意思是乘以sizeof(类型)(如上所示乘以3)。因此,如果你腐烂到1-D,你必须自己做。
要添加的另一件事,总是将维度的大小传递给必须将1-D阵列作为2-D的函数。像
int determinant(int *mat, int cols, rows);
编辑1:
只是要补充一点,如果你想在函数调用中保持数组完整,那么@JensGustedt ans也没问题。
答案 3 :(得分:1)
该功能的正确签名是
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)
),
您不必进行明确的dereference舞蹈,使您的代码更易于阅读和理解(并且可能更快;我看到一些编译器为*(*(a + i) + j)
生成的指令多于a[i][j]
,但不要依靠到处都是真实的)。
请记住,当大多数上下文中出现“N元素数组T
”的表达式时,它会转换为“指向T
的指针”的表达式,其值为数组中的第一个元素。由于对mat
的调用中的表达式printf
具有类型“3元素数组int
的3元素数组”,因此将其替换为“指向3的指针”类型的表达式元素数组int
“。
答案 4 :(得分:0)
如果我们将多维数组传递给函数:
int a2[5][7];
func(a2);
我们无法将该功能声明为接受pointer-to-pointer
func(int **a) /* WRONG */
{
...
}
该功能最终会收到pointer-to-an-array
,而不是pointer-to-a-pointer
。