3
#include <stdio.h>
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int *p = arr;
    ++*p;
    p += 2;
    printf("%d", *p);
    return 0;
}

The precedence of prefix ++ is greater than dereferencing, and hence, p should now point to the second element. And therefore, when we add 2 to it, it should point to the 4th element and answer should be 4. But, the answer is 3, why is that?

John Lui
  • 1,434
  • 3
  • 23
  • 37

8 Answers8

7

In the expression like ++*p precedence does not play any role at all. In this expression the inner operator applies to p (* in this case). The outer operator (++) applies to the result of the inner operator.

If you swap them around to obtain *++p, then ++ will apply to p, while * will apply to the result of ++p.

Every time you have a bunch of unary/postfix operators sitting together on the same side of the operand, they apply in the inside-out order.

For a right-hand side example, in p++[i] operator ++ applies to p and [i] applies to the result of p++. Meanwhile, in p[i]++ operator [i] applies to p and ++ applies to the result of p[i].

Precedence begins to play its role in "ambiguous" cases like:

  • Unary/postfix operator vs. binary operator, e.g.

    *p + 2
    

    In the above case unary * has higher precedence than binary +, resulting in (*p) + 2.

    p->i / 5
    

    Here postfix -> has higher precedence than binary /, resulting in (p->i) / 5.

    And in general unary/postfix operators have higher precedence than binary operators.

  • Unary vs. postfix operator, i.e. operators on both sides of the operand, e.g.

    *p++
    

    In the above case postfix ++ has greater precedence than unary *, resulting in *(p++).

    &p->i
    

    Here postfix -> has greater precedence than unary &, resulting in &(p->i).

    And in general postfix operators have higher precedence than unary operators.

  • Various more "exotic" cases like ?: operator...

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
2

There is no issue with precedence in the expression ++*p because there is no ambiguity to resolve. The operators are applied outwards from the operand. That is to say, *p is applied first, and ++ is applied to the result of that expression. The language doesn't allow for one operator to leapfrog in front of another.

Precedence rules would matter in the case where both operators could apply to the same operand, for example

*p++

This is not the case in your example.

Concerning the result, the increment does not affect p, which remains pointing to the first element of arr until you increment it with p += 2;. That makes p point to arr[2], which has value 3.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
2

p starts off pointing to the first element, arr[0].

In the prefix-++ operation, the element that p points at (*p, or arr[0]) is incremented, arr[0] now contains 2 instead of 1. The pointer itself doesn't change.

p (the pointer, not the element that it points to) is then incremented by 2, so p points to arr[2]... which has a value of... 3.

autistic
  • 1
  • 3
  • 35
  • 80
2

Because the first operation first dereference and then increments the one. The other operation increments the index from 0 to 2.

If you output arr[0] you see that the value was incremented.

See the precendence of the operator ++(prefix) and *(dereference). They have the same precendence and are in the same cell. Regarding to the Right-to-Left associativity. They are evaluated like this:

++(*p)

Operators that are in the same cell (there may be several rows of operators listed in a cell) are evaluated with the same precedence, in the given direction. For example, the expression a=b=c is parsed as a=(b=c), and not as (a=b)=c because of right-to-left associativity.

Working Example:

#include <stdio.h>
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int *p = arr;
    ++*p; 
    p += 2;
    printf("%d", *p);
    printf("%d", arr[0]);
    return 0;
}

Output:

32

http://ideone.com/6Xlt5N

Zelldon
  • 5,396
  • 3
  • 34
  • 46
1

Let me put the answer down:

++*p

first dereferences then increments value

*++p

increments pointer address then dereferences.

1

If you change the program to a bit more verbose mode :

#include <stdio.h>

int main()
    {
      int arr[] = {1, 2, 3, 4, 5};
      int *p = arr;
      printf("\n1- %p",p);
      ++*p;
      printf("\n2- %d",arr[0]);
      printf("\n3- %p",p);
      p += 2;
      printf("\n4- %p",p);
      printf("\n5- %d", *p);
      return 0;
    }

You will get the following output :

1- 0x7fff9fc53e30
2- 2     // changed the value pointer points to
2- 0x7fff9fc53e30  // pointer stays the same
3- 0x7fff9fc53e38
4- 3
DhruvPathak
  • 42,059
  • 16
  • 116
  • 175
1

Precednce resolves the operation order when two operatos can associate to the same operand. For example in 2*x+7 the precedence of * over + resolves the order of calculation as multiplication before addition: (2*x)+7.

In your case only one operator applies to p, and it is a dereference operator: *p. The pre-increment operator works on the dereferenced l-value: ++(*p) so precedence has nothing to do here.

CiaPan
  • 9,381
  • 2
  • 21
  • 35
1

About your question, the code ++*p is the value *p+1, not the address which p point to. The correct code is ++p. I hope this can help you.

cwfighter
  • 502
  • 1
  • 5
  • 20