22

很抱歉问了已经回答的问题,我是 C 的新手,不了解解决方案。这是我的功能

int rotateArr(int *arr) {
    int D[4][4];
    int i = 0, n =0;
    for(i; i < M; i ++ ){
        for(n; n < N; n++){
            D[i][n] = arr[n][M - i + 1];
        }
    }
    return D;
}

它抛出一个错误

main.c|23|错误:下标值既不是数组也不是指针也不是向量|

在线的

D[i][n] = arr[n][M - i + 1];

怎么了?我只是将一个数组元素的值设置为另一个数组元素。

传递的 arr 声明为

int S[4][4] = { { 1, 4, 10, 3 }, { 0, 6, 3, 8 }, { 7, 10 ,8, 5 },  { 9, 5, 11, 2}  };
4

6 回答 6

25

C 允许您[]在数组和指针上使用下标运算符。当您在指针上使用此运算符时,结果类型是指针指向的类型。例如,如果您申请[]int*结果将是int

这正是正在发生的事情:您正在传递int*,它对应于整数向量。在它上面使用下标一次就可以了int,所以你不能将第二个下标应用于它。

从您的代码中可以看出,它arr应该是一个二维数组。如果它被实现为一个“锯齿状”数组(即指针数组),那么参数类型应该是int **.

此外,您似乎正在尝试返回一个本地数组。为了合法地做到这一点,您需要动态分配数组,并返回一个指针。但是,更好的方法是struct为您的 4x4 矩阵声明一个特殊的,并使用它来包装您的固定大小的数组,如下所示:

// This type wraps your 4x4 matrix
typedef struct {
    int arr[4][4];
} FourByFour;
// Now rotate(m) can use FourByFour as a type
FourByFour rotate(FourByFour m) {
    FourByFour D;
    for(int i = 0; i < 4; i ++ ){
        for(int n = 0; n < 4; n++){
            D.arr[i][n] = m.arr[n][3 - i];
        }
    }
    return D;
}
// Here is a demo of your rotate(m) in action:
int main(void) {
    FourByFour S = {.arr = {
        { 1, 4, 10, 3 },
        { 0, 6, 3, 8 },
        { 7, 10 ,8, 5 },
        { 9, 5, 11, 2}
    } };
    FourByFour r = rotate(S);
    for(int i=0; i < 4; i ++ ){
        for(int n=0; n < 4; n++){
            printf("%d ", r.arr[i][n]);
        }
        printf("\n");
    }
    return 0;
}

这将打印以下内容

3 8 5 2 
10 3 8 11 
4 6 10 5 
1 0 7 9 
于 2013-11-11T14:16:55.467 回答
10

您没有正确传递二维数组。这应该适合你

int rotateArr(int *arr[])

或者

int rotateArr(int **arr) 

或者

int rotateArr(int arr[][N]) 

而不是返回数组,而是将目标数组作为参数传递。请参阅约翰博德的回答。

于 2013-11-11T14:19:14.813 回答
6

除非它是sizeofor 一元运算符的操作数&,或者是用于在声明中初始化另一个数组的字符串文字,否则“N 元素数组T”类型的表达式将被转换(“衰减”)为类型的表达式“指针T”,表达式的值是数组第一个元素的地址。

如果正在传递的数组的声明是

int S[4][4] = {...};

那么当你写

rotateArr( S );

表达式S的类型为“4 元素数组的 4 元素数组int”;由于S不是sizeofor 一元运算符的操作数&,它将被转换为类型为“指向 4 元素数组的指针”的表达式int,或者int (*)[4],这个指针值是实际传递给 的rotateArr。所以你的函数原型需要是以下之一:

T rotateArr( int (*arr)[4] )

或者

T rotateArr( int arr[][4] )

甚至

T rotateArr( int arr[4][4] )

在函数参数列表的上下文中,形式的声明T a[N]T a[]被解释为T *a; 这三个都声明a为指向T.

您可能想知道为什么我将返回类型从 更改intT. 如所写,您试图返回“4 元素数组的 4 元素数组int”类型的值;不幸的是,你不能这样做。C 函数不能返回数组类型,也不能分配数组类型。IOW,你不能写这样的东西:

int a[N], b[N];
...
b = a; // not allowed
a = f(); // not allowed either

函数可以返回指向数组的指针,但这不是你想要的。 D函数返回后将不复存在,因此您返回的任何指针都将无效。

如果要将旋转数组的结果分配给不同的数组,则必须将目标数组作为参数传递给函数:

void rotateArr( int (*dst)[4], int (*src)[4] )
{
  ...
  dst[i][n] = src[n][M - i + 1];
  ...
}

并将其称为

int S[4][4] = {...};
int D[4][4];

rotateArr( D, S );
于 2013-11-11T15:00:31.770 回答
3

问题是它arr不是(声明为)二维数组,而您将其视为二维数组。

于 2013-11-11T14:15:38.393 回答
0

你有“int* arr”所以“arr[n]”是一个int,对吧?然后您的“[M - 1 + 1]”位正试图将该 int 用作数组/指针/向量。

于 2013-11-11T14:19:26.450 回答
0

第二个下标运算符在这里无效。您将一个 int * 指针传递给函数,它是一个一维数组。所以只能使用一个下标运算符。

解决方案:您可以将 int ** 指针传递给函数

于 2016-06-19T17:10:14.390 回答