Reputation: 11
Please help me understand the reason the following code works the way it does:
#include <stdio.h>
int main(){
int a = 10;
void *b = &a;
int *p = b;
printf("%u",*p++);
return 0;
}
I know the output of printf will be 10, but I'm not quite following why *p++ is 10
Here are my steps:
1) void *b = &a;
stores the address of a in pointer b
2) int *p = b;
pointer p now points to the same data item as pointer b
3) printf("%u",*p++);
is where I get confused... the dereference of pointer p is a, which is 10... isn't *p++
basically the same as 10+1 which will be 11?
Upvotes: 1
Views: 537
Reputation: 3101
I just want to add my five cents.
For incrementing value indirected via pointer you can use ++*ip
or (*ip)++
. There is a nice explanation about parentheses in K&R book:
The parentheses are necessary in this last example
(*ip)++
; without them, them expression would increment ip instead of what it points to, because unary operators like * and ++ associate right to left.
And in your piece of code you got 10 because printf will print original value of variable and only after it wiil be incremented by one due of using of postfix ++
operator.
Upvotes: 1
Reputation: 1306
[C11: §6.5.2.4/2]: The result of the postfix ++ operator is the value of the operand. As a side effect, the value of the operand object is incremented (that is, the value 1 of the appropriate type is added to it).
The below statement
printf("%u",*p++);
is equivalent to
printf("%u",*p); /* p points to 'a' and value of `a` is 10. Hence, 10 is printed */
p = p + 1;
p
is of type pointer-to-int. Hence, 1
is scaled to sizeof (int)
.
As a result, p now points to an int
at address : p + sizeof (int)
Upvotes: 2
Reputation: 596
Variable p is a pointer to an int (pointing to a)
The expression *p dereferences the pointer, hence it's like accessing the int a directly.
Operator postfix ++ on pointer p takes precedence over the dereferencing. Therefore *p++ increments the pointer p (to whatever junk is in memory after int a) AFTER the expression is evaluated, so the dereferencing still resolves to a and that's why 10 is printed. But after the statement is run the value of p is changed. So, likely after that statement if you do printf("%u ",*p) you will get an awkward value.
If you do ++*p however, the expression is evaluated as ++ operation on the dereferenced int variable pointed by p. If you want to avoid trouble like this, when not sure, use parenthesis:
(*p)++
++(*p)
And you're making sure you are dereferencing the value and acting on it. Incrementing a pointer value is a very dangerous operation allowed by languages like C and C++, so avoid whenever possible!
Upvotes: 2
Reputation: 16424
*p++
is parsed as *(p++)
. p++
evaluates to p
, and then increments p
, so the change won't be seen until the next reference to p
. So *p
is 10, *p++
is 10 (but p now points to &a+1
), *++p
is undefined behavior (because *(&a+1)
is not a valid value), (*p)++
is 10 but changes a
to 11, and ++*p
(or ++(*p)
) is 11 (as is a
).
Upvotes: 2
Reputation: 12745
The post-increment operator in the expression *p++
applies to the pointer, not the value stored at that location, so the result is never 11, before or after it is evaluated. The expression *p++
means: dereference p
(get it's value) then increment p
one location. Since p
points to an int
, incrementing it will move it forward sizeof(int)
bytes . The addition does not ever apply to the value that p
points to, which is 10.
However, the expression (*p)++ is different. It dereferences p (gets its value) and then increments the value in that memory location. The expression evaluates to the original value. So after executing the statement
int c = (*p)++;
the variable c
would equal 10, while a
would equal 11.
Upvotes: 2
Reputation: 9940
*p++
is essentially *(p++)
. It evaluates to the value of p
before it is incremented which is the address to a
. Then you dereference it which evaluates to the value 10
.
Upvotes: 3