试图将2个矩阵相乘
void Multiply(float* A, float* B, float* C)
{
int m = sizeof(A) / sizeof(A[0]);
int p = sizeof(A[0]) / sizeof(A[0][0]);
int n = sizeof(B) / sizeof(B[0]);
int i, j, k;
for (i = 0;i < m;i++)
for (j = 0;j < n;j++)
{
C[n*i + j] = 0;
for (k = 0;k < p;k++)
C[n*i + j] = C[n*i + j] + A[p*i + k] * B[n*k + j];
}
}
我在此行收到错误invalid types 'float[int]' for array subscript
int p = sizeof(A[0]) / sizeof(A[0][0]);
我在做什么错了?
答案 0 :(得分:2)
在调用Multiply
的例程中,A
可以定义为float A[X][Y];
。但是,Multiply
仅接收一个指针,而不接收数组。另外,Multiply
不会收到有关原始数组大小的信息,因此无法在子例程中计算它们。它们必须由呼叫者传递。
在表达式中使用数组时,包括函数参数但不包括sizeof
或一元&
(或用于初始化数组的字符串文字)的操作数,它将自动转换为指向第一个元素的指针。
如果A
是X
Y
的{{1}}数组,则float
的第一个元素是A
的数组Y
。因此,将float
用作函数参数时,它将自动转换为类型A
。这与参数声明float (*)[Y]
不同。指向float *
数组的指针与指向float
的指针不兼容,编译器应对此发出警告。
尽管如此,如果在编译程序时忽略了警告或强制类型转换以覆盖类型,则float
对于Multiply
仅具有float *
。它没有有关数组大小或数组事实的信息。然后,在表达式A
(不需要括号)中,sizeof(A) / sizeof(A[0])
是指向sizeof(A)
的指针的大小,因为float
是指向{{1的指针}}和sizeof(A [0])A
浮动float
A [0] is the size of a
浮动, because
A is a
乘以(as it must be since
浮动*`)。
参数in
在大小计算上存在相同的问题。在is a
中,B
只是指向Multiply
的指针,大小B
仅计算指针的大小除以float
的大小。它不提供原始数组的大小。
奇怪的是,您的代码同时使用sizeof(B) / sizeof(B[0])
作为float
中的二维数组和A
中的一维数组。您必须选择其中之一。
如果编译器支持可变长度数组,则可以将A[0][0]
声明为:
A[p*i + k]
然后,您可以在例程中使用Multiply
,void Multiply(int m, int p, int n, float (*A)[p], float (*B)[n], float (*C)[n])
和A[i][k]
。在调用例程中,您将像B[k][j]
一样将原始数组写为参数,其中C[i][j]
,Multiply(X, Y, Z, A, B, C)
和X
是必需的维。
另一种方法是将数组作为指向Y
的指针而不是指向可变长度数组的指针:
Z
然后,您将使用float
,如当前代码所示。在调用例程中,您将传递指向数组void Multiply(int m, int p, int n, float *A, float *B, float *C)
的{{1}}元素的指针。
就目前而言,这可能会出现别名和指针算术问题,因为结果代码使用标称数组之外的索引计算来访问A[p*i + k]
元素。编译器通常支持它,但是您应该检查一下。