Array increment operator in C

I do not understand the results of the 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 raise the following error?

error: lvalue required as increment operand

+7
c pointers post-increment
source share
7 answers

Part-1:

The array names are constant (lvalue is not changed), you can add a value to the array name, but you cannot change it.

The expression a + 2 does not change a itself, but if you are doing a++ , which is equivalent to a = a + 1 , try changing the name of the array --lvalue error. The expression a++ in the second printf is incorrect - an example of a semantic phase error. read the following language standards:

6.3.2.1 Lvalues, arrays, and function pointers

724 The lvalue modifiable value is a l value that does not have an array type, does not have an incomplete type, does not have a const-qual type, and if it is a structure or union, does not have a member (including, recursively, any member or element from all aggregates or associations) with a categorical type.

729 Unless it is an operand of the sizeof operator or a unary operator & or is a string literal used to initialize an array, an expression that is of type "array of type" is converted to an expression of type "pointer to type" pointing to the starting element of the array and not lvalue .

Part 2:

Please note that the names of arrays in most expressions decay at the address of the first element (read some exceptions in which the name of the array does not fade into a pointer to the first element? @H <sub> 2sub> SO <sub> 3sub> skillfully answered).

When you do a + 2 , its result is the address of the third element (or the address of the element in index 2 ). Thus, a + 2 coincides with &a[2] . This address is not a value in the index.

To print the address, use %p instead of %d and the type address in void* as follows:

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

To print the value, you need the protective 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 the first printf 2012 function?

No, pointer arithmetic is different than integer arithmetic. Since we know that the name of the array decays to the address of the address of the first element in most expressions So, when you do a + 2 , this is the address of the third element, which is at index 2 . Suppose if the size of int on your system is 4 bytes, then a + 2 stat indicating the location of 2018, according to your assumption that the value of a is 2010.

To understand, read 10.2 Pointers and Arrays; Arithmetic of pointers and Arithmetic of pointers .

+11
source share
 int a[4]={1,3,5,6}; printf("%d\n",a++); // you should not modify array name illegal in c 

Suppose pa is an integer pointer

A pointer is a variable, so pa=a and pa++ are legal. But an array name is not a variable; constructions like a=pa and a++ are illegal.

+2
source share

I think the first conclusion will depend on how the integer type is represented on your computer. If one integer occupies 4 bytes in memory, the output should be 2018, i.e. 2010 + 2 * 4. The second printf may cause a compilation error.

+2
source share

At first, this program causes undefined behavior , and I'm a little discouraged by the fact that with so many answers, none of them mention it. In both printf tags, your argument is a pointer, but you specify the format as %d , which is expected, and int it should be% p . draft draft C99 in section 7.19.6.1 The function fprintf, in which printf refers back to the format string, in clause 9 it is indicated:

If the conversion specification is not valid, the behavior is undefined. [...]

Returning to your question, the expression a++ throws an error because the postfix increment requires that its operand be a modifiable value of lvalue, the draft standard in section 6.5.2.4 The postfix increment and decrement operators in paragraph 1 (my underline):

The operand of the increment or decrement operator of a postfix must be of an unqualified real or pointer type and must be a mutable value of l .

we can see from the values 6.3.2.1 values, arrays and designations of functions in paragraph 1:

[...] The lvalue modifiable value is an l value that does not have an array type [...]

+2
source share

The memory addresses of the array remain constant, so you cannot change them. This is what you do in ++ instruction. Therefore, the compiler will throw an error.

+1
source share

a is not an int variable, it is a pointer to an integer, so to print it you need to first dereference it

 printf("%d\n", *(a + 2)); 
0
source share

The name of the array is a constant pointer and therefore will always point to the 0th element of this array. This is not a variable, so we cannot assign it any other address, and we cannot move it by increasing or decreasing it. Consequently

 a = &var; /*Illegal*/ a++; /*Illegal*/ a = a-1; /*Illegal*/ 
0
source share

All Articles