简体   繁体   中英

Incrementing a 2D array in C

I have just started learning 2D arrays in C and I came across this code where a 2D array is directly pre-incremented like this ++array .

I tried to print the matrix in 3 different places(After initializing, in function after increment, in main function after function call), but I can't understand how the pre-incrementation works.

I also noticed that a[1][1]++ is reflected in the original matrix(8 is incremented to 9) but nothing else.

#include <stdio.h>
void printmatrix(int[3][3]);
int function(int a[][3])
{
    int i,j;
    ++a; //what does this do?
    printf("In function...\n");
    printmatrix(a);
    a[1][1]++;
}
void printmatrix(int a[3][3])
{
    int i,j;
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++)
        {
            printf("%d ",a[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

int main()
{
int a[3][3]={1,2,3,4,5,6,7,8,9};
printf("Initially...\n");
printmatrix(a);
function(a);
printf("In main...\n");
printmatrix(a);
printf("a[2][1]-a[1][2]=%d",a[2][1]-a[1][2]);
return 0;
}

The output that I got is,

Initially...
1 2 3 
4 5 6 
7 8 9 

In function...
4 5 6 
7 8 9 
32765 0 0 

In main...
1 2 3 
4 5 6 
7 9 9 

a[2][1]-a[1][2]=3

Also when I tried to pre-increment the array after declaring it in the main function I got the following error.

int a[3][3]={1,2,3,4,5,6,7,8,9};
a++;
main.c: In function ‘main’:
main.c:28:2: error: lvalue required as increment operand
 a++;

You cannot increment an array, that makes no sense. You can increment a pointer. Pointers and arrays are two different things.

++a; //what does this do?

This increments a pointer , because a is a pointer. Although it is declared as int a[][3] , it is not a 2D array.

Why is it a pointer and not an array? Because it is a function parameter. A function parameter cannot be an array. You can declare it with square brackets, but it still won't be an array. It means exactly the same thing as int (*a)[3] — only if it is a function parameter. In printmatrix too. This is important .

It is a pointer to a 1D array, which is the first element of a 2D array aka an array of arrays. After the increment takes place, it starts pointing to the second element of the same array. If you think of your 2D array as a matrix, it now points to the second row of the matrix. That's what incrementing a pointer does. If it pointed to the n th element of an array before, it will point to the n+1 th element afterwards (and elements of this particular array are 1D arrays, aka rows).

This makes printing that happens in printmatrix(a); undefined behaviour . a now points to the second element of a 2D array, but printmatrix has no idea about it, and prints as if there are still 3 rows ahead of it.

Also when I tried to pre-increment the array after declaring it in the main function I got the following error.

That's right, because in main , a is an array, not a pointer. You cannot increment an array.

I have just started learning 2D arrays in C and I came across this code where a 2D array is directly pre-incremented like this ++array .

No, you didn't. At least not in a program that any C compiler I know would accept. Arrays often contain modifiable elements, but whole arrays are not modifiable units.

In this function ...

 int function(int a[][3]) { int i,j; ++a; //what does this do? printf("In function...\\n"); printmatrix(a); a[1][1]++; }

... although parameter a is expressed using array syntax, it is in fact a pointer, not an array. This is a quirk of C, though it works out pretty consistently with other C semantics around arrays. The function signature is equivalent to ...

int function(int (*a)[3])

..., which declares a as a pointer to an array of 3 int s. Thus, the ++a within has its normal effect: it computes a pointer to the next int[3] following *a and updates a to point to that.

Now consider main() :

 int main() { int a[3][3]={1,2,3,4,5,6,7,8,9}; printf("Initially...\\n"); printmatrix(a); function(a); // [...]

In main() , identifier a designates a 2D array, but with a couple of notable exceptions, wherever it appears in an expression, it is converted to a pointer to its first element. Such a pointer has exactly the type that function() expects for its parameter, so the function call is just fine.

Note well that C function calls have strictly pass-by-value semantics. The function receives its own copy of that pointer, so changes it makes do not affect the pointer value in main() (which has no enduring storage) much less the array from which it was derived.

Also when I tried to pre-increment the array after declaring it in the main function I got the following error.

 int a[3][3]={1,2,3,4,5,6,7,8,9}; a++;

As I wrote already, whole arrays are not modifiable. The diagnostic message produced by your compiler is a bit off, however. The a in that fragment is an lvalue. But it is not a modifiable lvalue, which is what the pre- and post-increment operators require for an operand.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM