Reputation: 49
void x(){
int x[] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
int *p = x + 1;
while (*p++ >5)
printf ("%d ", *p);
printf ("\n");
}
Output: {7, 6, 5}
I wanted to double check my rationale behind what the proper output for this is, given the precedence and associativity in C.
When the function is called, it executes top down, taking no arguments.
First we have an array x of 9 elements.
Second we have a pointer p, which points to element x[1];
Third, we jump into the while loop, which is true for everytime *p++ > 5. What is evaluated first here is post incrementing the address of p++, so for the first element x[1], we have a value of 8 which is greater than 5, so p is incremented (p++ = x[2] = 7) x[2] = 7 becomes the new *p value (since it points to x[2] now) and 7 is printed.
Next we have 7 which is greater than 5, p is incremented (p++ = x[3] = 6) so 6 is printed and then we have 6 which is still greater than 5, p is incremented (p++ = x[4] = 5) so 5 is printed, we have so far {7, 6, 5} printed.
Then we evaluate the position of x[4] which is 5, which is not greater than 5, so we jump out of the while loop and ends up with the output. {7, 6, 5}.
Is my reasoning for this question correct?
Upvotes: 2
Views: 234
Reputation: 160
*p++ -> post increment/pre increment operator is having high precedence level than dereference operator. First pointer p is incremented. If it is pre increment operator than p is incremented to next address and then pointer is dereferenced. But in case of post increment the pointer increment will be postponed until the pending operation on the pointer p is completed i.e. dereferencing operation.
Your understanding is correct.
Upvotes: -3
Reputation: 154562
Is my reasoning for this question correct?
Yes, aside from step 3.
while (*p++ >5)
*p++ > 5
retrieves the value of p
: the first time a pointer to x[1]
or 8. That original value of p
is used to de-referenced and fetch the int
8. 8
is compared to 5
.
Sometime during the above, p
is incremented - before the next sequence point. C does not specify when the that happens other than the value used to de-reference was the original value of pointer p
.
Upvotes: 0
Reputation: 160
Postfix increment/decrement have high precedence, but the actual increment or decrement of the operand is delayed (to be accomplished sometime before the statement completes execution). So in the statement y = x * z++; the current value of z is used to evaluate the expression (i.e., z++ evaluates to z) and z only incremented after all else is done
Upvotes: 1
Reputation: 44370
Is my reasoning for this question correct?
Since the lines
while (*p++ >5)
printf ("%d ", *p);
in a more simple form is equivalent to
while (*p >5)
{
p = p + 1; // Or: p++; Or: ++p;
printf ("%d ", *p);
}
then yes, your reasoning is correct
If you are at beginner level I'll recommend that you avoid using pre-increment (++x
) and post-increment (x++
) in complex expressions. They are the cause of so many beginner mistakes. Only use them as single expressions. Keeping things simple, avoids many bugs.
Upvotes: 4
Reputation: 311126
You can imagine the while statement
while (*p++ >5)
the following way
while ( 1 )
{
int *tmp = p;
++p;
int value = *tmp;
if ( !( value > 5 ) ) break;
//...
}
As you can see neither element of the array is changed.
Initially p
points to x[1]
. So the value of x[1]
is compared with 5
while the pointer p
itself moves one position right and inside the body of the loop it points to x[2]
and the value of x[2]
is outputted. And so on.
Take into account that the postincrement operator has higher priotity than the dereferencing operator and the value of the postincrement operator is the value of its operand before incrementing.
Consider also this simple demonstrative program.
#include <stdio.h>
int main(void)
{
int a[] = { 1, 2 };
int *p = a;
printf( "%d\n", *p++ );
printf( "%d\n", *p );
return 0;
}
Its output is
1
2
Upvotes: 3