1

I am trying to understand the usage of *ptr++. Below is the code I have used (Scenario 1)

#include<iostream> 

int main()

{
    int a[5];
    a[0] = 3;
    a[1] = 2;
    a[2] = 4;
    a[3] = 7;
    a[4] = 9;
    int* ptr;
    ptr = &a[0];

    std::cout << *ptr << " ";
    std::cout << *ptr++ ;

}

I have read that the precedence is '++' first, and then dereferencing. So I expected that the output would be 3 2. However, the output I obtained is 3 3.

Now, in Scenario 2, if I try

int* ptr;
ptr=&a[0];
*ptr++;
std::cout<< *ptr;

(with all lines of code before int* ptr remaining the same), I obtain the output as 2.

So how is *ptr++ working, and in Scenario 2, isn't *ptr++ working the same as a simple ptr++?

  • You need to do ++ptr if you want to increment ptr before dereferencing. `std::cout << *ptr << " "; std::cout << *++ptr ;` prints `3 2` More on this here: https://stackoverflow.com/questions/4445706/post-increment-and-pre-increment-concept – Jean-Marc Volle May 12 '20 at 12:08
  • Okay, yes, understood, thank you! – Pranav Krishnan May 12 '20 at 12:17

3 Answers3

3

Precedence means that *ptr++ is interpreted as *(ptr++) instead of (*ptr)++.

What surprised you is the unusual meaning of (ptr++). That meaning is "increment ptr, but first use the old value". So *(ptr++) dereferences the old value of ptr.

The statement *ptr++; ignores the value you got by dereferencing ptr++, but still does the increment.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • @PranavKrishnan. `ptr` is indeed updated to `&a[1]`, but `*` still works on `&a[0]`, and that's what is printed. Also, you assume the order of precedence is also the order of execution, which is just not the case. – MSalters May 12 '20 at 12:17
1

*ptr++ does the following steps:

  1. Create a copy of ptr (part of post-increment operation)
  2. Dereference copy returned by post-increment using *
  3. Increment ptr (part of post-increment operation)

So when you write std::cout << *ptr++;, you print dereferenced copy of original ptr (from before incrementing).

When you separate it to two lines like this:

*ptr++;
std::cout<< *ptr;

It becomes equivalent to this:

ptr++;
std::cout<< *ptr;

-you discard the dereference result in *ptr++; and dereference the already incremented pointer later in std::cout <<

Yksisarvinen
  • 18,008
  • 2
  • 24
  • 52
1

You said that "I have read that the precedence is '++' first, and then dereferencing", and this is where you made mistake.

From https://en.cppreference.com/w/cpp/language/operator_precedence, you can see a++ a-- Suffix/postfix increment and decrement has higher precedence(Precedence 2) while *a Indirection (dereference) is only Precedence 3.

The smaller is the number, the higher is the precedence This is why *ptr++ should be interpreted as *(ptr++)

Ter
  • 90
  • 7