[c] C subscripted value is neither array nor pointer nor vector when assigning an array element value

Sorry for asking the already answered question, I am a newbie to C and don't understand the solutions. Here is my function

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

It throws an error

main.c|23|error: subscripted value is neither array nor pointer nor vector|

on line

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

What's wrong? I am just setting the value of an array element to another array element.

The arr passed is declared as

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

This question is related to c arrays

The answer is


The problem is that arr is not (declared as) a 2D array, and you are treating it as if it were 2D.


You have "int* arr" so "arr[n]" is an int, right? Then your "[M - 1 + 1]" bit is trying to use that int as an array/pointer/vector.


You are not passing your 2D array correctly. This should work for you

int rotateArr(int *arr[])

or

int rotateArr(int **arr) 

or

int rotateArr(int arr[][N]) 

Rather than returning the array pass the target array as argument. See John Bode's answer.


the second subscript operator is invalid here. You passed a int * pointer into function, which is a 1-d array. So only one subscript operator can be used on it.

Solution : you can pass int ** pointer into funciton


Except when it is the operand of the sizeof or unary & operator, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" is converted ("decays") to an expression of type "pointer to T", and the value of the expression is the address of the first element of the array.

If the declaration of the array being passed is

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

then when you write

rotateArr( S );

the expression S has type "4-element array of 4-element array of int"; since S is not the operand of the sizeof or unary & operators, it will be converted to an expression of type "pointer to 4-element array of int", or int (*)[4], and this pointer value is what actually gets passed to rotateArr. So your function prototype needs to be one of the following:

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

or

T rotateArr( int arr[][4] )

or even

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

In the context of a function parameter list, declarations of the form T a[N] and T a[] are interpreted as T *a; all three declare a as a pointer to T.

You're probably wondering why I changed the return type from int to T. As written, you're trying to return a value of type "4-element array of 4-element array of int"; unfortunately, you can't do that. C functions cannot return array types, nor can you assign array types. IOW, you can't write something like:

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

Functions can return pointers to arrays, but that's not what you want here. D will cease to exist once the function returns, so any pointer you return will be invalid.

If you want to assign the results of the rotated array to a different array, then you'll have to pass the target array as a parameter to the function:

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

And call it as

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

rotateArr( D, S );