Array increment operator in C

user221458 picture user221458 · Oct 2, 2013 · Viewed 15k times · Source

I don't understand the results of following code:

#include <stdio.h>
#include <conio.h>
int main()
{
   int a[4]={1, 3, 5, 6};
   //suppose a is stored at location 2010
   printf("%d\n", a + 2);
   printf("%d", a++);
   return 0;
}

Why does the second printf function produce following error?

error: lvalue required as increment operand

Answer

Grijesh Chauhan picture Grijesh Chauhan · Oct 2, 2013

Part-1:

Array names are constant (not modifiable lvalue), your can add value to array name but can't modify it.

Expression a + 2 doesn't modify a itself but when you do a++ that is equivalent to a = a + 1 try to modify array name --lvalue error. The expression a++ in second printf is wrong - an example of semantic phase error. read following language standards:

6.3.2.1 Lvalues, arrays, and function designators

724 A modifiable lvalue is an lvalue that does not have array type, does not have an incomplete type, does not have a const-qualified type, and if it is a structure or union, does not have any member (including, recursively, any member or element of all contained aggregates or unions) with a const-qualified type.

729 Except when it is the operand of the sizeof operator or the unary & operator, or is a string literal used to initialize an array, an expression that has type “array of type” is converted to an expression with type “pointer to type” that points to the initial element of the array object and is not an lvalue.

Part-2:

Note array names in most expressions decays in address of first element (read some exceptions where array name not decaying into a pointer to first element? ably answered by @H2CO3).

When you do a + 2 its result is address of third element (or address of element at index 2) So a + 2 is same as &a[2] It is address not value at index.

To print address use %p instead of %d and typecast address into void* as follows:

printf("address (a + 2) = %p , &a[2] = %p", (void*)(a + 2), (void*)(&a[2]));

To print value you need defence operator * as follows:

printf("address *(a + 2) = %d , a[2] = %d", *(a + 2), a[2]);   

Part-3:

suppose a is stored at location 2010, Is the output of first printf function 2012?

No, pointer arithmetic is different then integer arithmetic. As we know array name decays into address of first element's address in most expressions So when you do a + 2 the value is address of third element that is at index 2. So suppose if int size in your system is 4 bytes then a + 2 stat pointing to location 2018 according to your assumption that a address value is 2010.

To understand read 10.2 Pointers and Arrays; Pointer Arithmetic and Pointer Arithmetic.