首页 文章

在分配数组元素值时,C预订值既不是数组也不是指针,也不是向量

提问于
浏览
12

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

6 回答

  • 0

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

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

    从您的代码中可以看出 arr 应该是一个二维数组 . 如果它实现为"jagged"数组(即指针数组),则参数类型应为 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
    
  • 6

    除非它是 sizeof 或一元 & 运算符的操作数,或者是用于初始化声明中的另一个数组的字符串文字,否则类型为“N-element array of T " is converted ("衰减") to an expression of type "指向 T ”的表达式,以及表达式的值是数组的第一个元素的地址 .

    如果传递的数组的声明是

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

    然后当你写

    rotateArr( S );
    

    表达式 S 的类型为“4元素数组 int 的4元素数组”;由于 S 不是 sizeof 或一元 & 运算符的操作数,因此它将转换为“指向 int 的4元素数组的指针”或 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 的指针 .

    您可能想知道为什么我将返回类型从 int 更改为 T . 如上所述,您正在尝试返回类型为“4元素数组 int 的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 );
    
  • 14

    您没有正确传递2D数组 . 这应该适合你

    int rotateArr(int *arr[])
    

    要么

    int rotateArr(int **arr)
    

    要么

    int rotateArr(int arr[][N])
    

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

  • 0

    问题是 arr 不是(声明为)2D数组,并且您将其视为2D .

  • 3

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

  • 6

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

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

相关问题