【问题标题】:C subscripted value is neither array nor pointer nor vector when assigning an array element value分配数组元素值时,C下标值既不是数组也不是指针也不是向量
【发布时间】:2013-11-11 14:13:26
【问题描述】:

很抱歉提出已经回答的问题,我是 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}  };

【问题讨论】:

  • 也许你是想写int rotateArr(int **arr)

标签: c arrays


【解决方案1】:

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

这正是正在发生的事情:您正在传递int*,它对应于一个整数向量。在其上使用下标一次使其成为int,因此您不能对其应用第二个下标。

从您的代码看来,arr 应该是一个二维数组。如果实现为“锯齿状”数组(即指针数组),则参数类型应为int **

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

// 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;
}

这个prints the following

3 8 5 2 
10 3 8 11 
4 6 10 5 
1 0 7 9 

【讨论】:

    【解决方案2】:

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

    int rotateArr(int *arr[])
    

    int rotateArr(int **arr) 
    

    int rotateArr(int arr[][N]) 
    

    将目标数组作为参数传递,而不是返回数组。请参阅 John Bode 的回答。

    【讨论】:

    • int **int [][N] 不等价。
    • 即使有演员(int **)Sint **也不能代表int[4][4],而(int *arr[])必须是(int (*arr)[4])
    • Acme,看约翰·博德的回答
    【解决方案3】:

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

    如果被传递的数组的声明是

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

    那么当你写的时候

    rotateArr( S );
    

    表达式S 的类型为“int 的 4 元素数组的 4 元素数组”;由于S 不是sizeof 或一元&amp; 运算符的操作数,它将被转换为“指向int 的4 元素数组的指针”或int (*)[4] 类型的表达式,并且此pointer 值是实际传递给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 的指针。

    您可能想知道为什么我将返回类型从 int 更改为 T。如所写,您正在尝试返回“int 的 4 元素数组的 4 元素数组”类型的值;不幸的是,你不能这样做。 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 );
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • @Euphe - 看我的回答。
      【解决方案5】:

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-07-05
          • 1970-01-01
          • 1970-01-01
          • 2013-07-20
          相关资源
          最近更新 更多