2
votes
int * matrixsum(int *a,int *b,int n,int m)
{
    int *p=NULL,i,j;
    p=malloc(sizeof(int)*n*m);
    if(p==NULL)
    {
        printf("Error!\n");
        exit(1);
    }
    for(i=0;i<n;i++)
    {
        for(j=0;j<m;j++)
        {
            *(p+i*n+j)=*(a+i*n+j)+*(b+i*n+j);
        }
    }
    return p;
}

My question is about the line *(p+i*n+j)=*(a+i*n+j)+*(b+i*n+j);: if I replace it with p[i][j]=a[i][j]+b[i][j]; I get the following error 3 times:

error: subscripted value is neither array nor pointer nor vector

Why? From my knowledge they are the same thing.

My compiler is gcc version 4.6.3.

4
You have to say p[i * n +j] etc. You only have a one-dimensional array. - Kerrek SB
Unrelated: Your index-arithmetic is wrong, *(p+i*n+j)=*(a+i*n+j)+*(b+i*n+j); should use m instead of n. - Daniel Fischer
Arrays and pointers are absolutely not the same thing. Read section 6 of the comp.lang.c FAQ. - Keith Thompson
Note that the "vector" in the error message probably refers to a gcc extension, not to C++ vectors. - Keith Thompson
@KeithThompson that's good to know. - Cristi

4 Answers

5
votes

They're not the same thing at all — which is why the compiler is complaining! You could write:

p[i*n+j] = a[i*n+j] + b[i*n+j];

The type of p is int *; therefore the type of p[i] is int, and you can't subscript an int. You'd have to be passing a 2D-array of int, or an array of pointers to int, to be able to use the p[i][j] notation. For example, in C99 (using variable-length arrays — and note the reordering of the parameters):

int *matrixsum(int n, int m, int a[m][n], int b[m][n])
{
    ...
    p[i][j] = a[i][j] + b[i][j];
    ...
}

Or, with some considerable care in the setup, you could use:

int *matrixsum(int **a, int **b, int m, int n)
{
    ...
    p[i][j] = a[i][j] + b[i][j];
    ...
}

Note that for this latter example, you can't simply write:

int a[4][4] = { ... };
int b[4][4] = { ... };
int r = matrixsum(a, b, 4, 4);

The memory allocation for the 2D array is quite different from what is required for the int ** notation.

1
votes

from my knowledge they are the same thing

Yes, you've converted from linear indexing to subscripts correctly, but all 3 of those variables are of the wrong type to apply those subscripts. They need to be of type int ** for you to be able to do 2-D array indexing.

1
votes

The compiler is simply telling you that you can't de-reference an integer. p is only an int pointer - similarly for a, b, and c. You can simulate p[i][j] by doing the tricky pointer arithmetic into your buffer, but you can't de-reference an int.

These variables must be int ** before you can use them as a 2D array, using array subscripts.

1
votes

In the second form, how can the compiler guess that n is the length of the first dimension of YOUR tab (not his one) ? to compute &t[i][j] == *(t + i * n + j)