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

Eup*_*phe 14 c arrays

很抱歉询问已经回答的问题,我是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;
}
Run Code Online (Sandbox Code Playgroud)

它抛出一个错误

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}  };
Run Code Online (Sandbox Code Playgroud)

das*_*ght 16

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;
}
Run Code Online (Sandbox Code Playgroud)

打印出以下内容:

3 8 5 2 
10 3 8 11 
4 6 10 5 
1 0 7 9 
Run Code Online (Sandbox Code Playgroud)


Sad*_*que 6

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

int rotateArr(int *arr[])
Run Code Online (Sandbox Code Playgroud)

要么

int rotateArr(int **arr) 
Run Code Online (Sandbox Code Playgroud)

要么

int rotateArr(int arr[][N]) 
Run Code Online (Sandbox Code Playgroud)

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

  • `int **` 和 `int [][N]` 不等价。 (3认同)

Joh*_*ode 6

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

如果传递的数组的声明是

int S[4][4] = {...};
Run Code Online (Sandbox Code Playgroud)

然后当你写

rotateArr( S );
Run Code Online (Sandbox Code Playgroud)

表达式S有"4元素阵列的4元素数组int"; 因为S它不是sizeof或一元运算&符的操作数,它将被转换为"指向4元素数组的指针"类型的表达式int,或者int (*)[4],此指针值实际上是传递给它的rotateArr.所以你的函数原型需要是以下之一:

T rotateArr( int (*arr)[4] )
Run Code Online (Sandbox Code Playgroud)

要么

T rotateArr( int arr[][4] )
Run Code Online (Sandbox Code Playgroud)

甚至

T rotateArr( int arr[4][4] )
Run Code Online (Sandbox Code Playgroud)

在一个函数参数列表的上下文中,形式的声明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
Run Code Online (Sandbox Code Playgroud)

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

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

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

并称之为

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

rotateArr( D, S );
Run Code Online (Sandbox Code Playgroud)