在尝试将 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]);
我做错了什么?
最佳答案
在调用 Multiply
的例程中, A
可能定义为 float A[X][Y];
.然而,Multiply
只接收一个指针,而不是一个数组。另外,Multiply
没有收到有关原始数组大小的信息,因此无法在子例程中计算它们。它们必须由调用者传递。
在表达式中使用数组时,包括函数参数但不包括 sizeof
的操作数或一元 &
(或用于初始化数组的字符串文字),它会自动转换为指向其第一个元素的指针。
如果A
是 X
的数组Y
的数组float
, 然后是 A
的第一个元素是 Y
的数组float
.因此,当A
用作函数参数,它会自动转换为类型 float (*)[Y]
.这与参数声明不同,后者是 float *
.指向 float
数组的指针与指向 float
的指针不兼容,你的编译器应该警告你。
如果您仍然在忽略警告或强制转换以覆盖类型的情况下编译程序,那么 Multiply
只有一个float *
对于 A
.它没有关于数组大小的信息,也没有关于数组的数组的信息。然后,在表达式 sizeof(A) / sizeof(A[0])
中(括号是不必要的),sizeof(A)
是指向 float
的指针的大小,因为 A
是指向 float
的指针, 和 sizeof(A[0]) is the size of a
float , because
A[0] is a
float (as it must be since
in
相乘is a
float *`)。
参数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)
然后你会使用A[p*i + k]
如您当前的代码所示。在调用例程中,您将传递指向 [0][0]
的指针数组元素:Multiply(X, Y, Z, &A[0][0], &B[0][0], &C[0][0])
.
迂腐地,这可能有别名和指针算术问题,因为生成的代码访问 float
在标称数组之外使用索引计算的元素。它通常在编译器中受支持,但您应该检查一下。
关于c - 尝试获取二维数组的列长度时,数组下标的无效类型 'float[int]',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56280520/