Toni He
Toni He

Reputation: 49

Explanation behind arithmetic pointer post increment output in C

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

Answers (5)

Ravi
Ravi

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

chux
chux

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

Ravi
Ravi

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

4386427
4386427

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

Vlad from Moscow
Vlad from Moscow

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

Related Questions