尝试获取二维数组的列长时,数组下标的类型'float [int]'无效

时间:2019-05-23 17:48:25

标签: c arrays

试图将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]);

我在做什么错了?

1 个答案:

答案 0 :(得分:2)

在调用Multiply的例程中,A可以定义为float A[X][Y];。但是,Multiply仅接收一个指针,而不接收数组。另外,Multiply不会收到有关原始数组大小的信息,因此无法在子例程中计算它们。它们必须由呼叫者传递。

在表达式中使用数组时,包括函数参数但不包括sizeof或一元&(或用于初始化数组的字符串文字)的操作数,它将自动转换为指向第一个元素的指针。

如果AX 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]

然后,您可以在例程中使用Multiplyvoid 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]元素。编译器通常支持它,但是您应该检查一下。