If you are not using parenthesis to specify the order of operations, both prefix and postfix increments have precedence over reference and dereference. However, prefix increment and postfix increment are different operations. In ++x, the operator takes a reference to your variable, add one to it and return it by value. In x++, the operator increment your variable, but returns its old value. They behave sort of like this (imagine they are declared as methods inside your class):
//prefix increment (++x)
auto operator++()
{
(*this) = (*this) + 1;
return (*this);
}
//postfix increment (x++)
auto operator++(int) //unfortunately, the "int" is how they differentiate
{
auto temp = (*this);
(*this) = (*this) + 1; //same as ++(*this);
return temp;
}
(Note that there is a copy involved in the postfix increment, making it is less efficient. That's the reason why you should prefer ++i instead of i++ in loops, even though most compilers do it automatically for you these days.)
As you can see, postfix increment is processed first, but, because of the way it behaves, you will be dereferencing the prior value of the pointer.
Here is an example:
char * x = {'a', 'c'};
char y = *x++; //same as *(x++);
char z = *x;
In the second line, the pointer x will be incremented before the dereference, but the dereference will happen over the old value of x (which is an address returned by the postfix increment). So y will be initialized with 'a', and z with 'c'. But if you do it like this:
char * x = {'a', 'c'};
char y = (*x)++;
char z = *x;
Here, x will be dereferenced and the value pointed by it ('a') will be incremented (to 'b'). Since the postfix increment returns the old value, y will still be initialized with 'a'. And since the pointer didn't change, z will be initialized with the new value 'b'.
Now let's check the prefix cases:
char * x = {'a', 'c'};
char y = *++x; //same as *(++x)
char z = *x;
Here, the dereference will happen on the incremented value of x (which is immediately returned by the prefix increment operator), so both y and z will be initialized with 'c'. To get a different behavior, you can change the order of the operators:
char * x = {'a', 'c'};
char y = ++*x; //same as ++(*x)
char z = *x;
Here you ensure that you are incrementing the content of x first and the value of the pointer never change, so y and z will be assigned with 'b'. In the strcpy function (mentioned in other answer), the increment is also done first:
char * strcpy(char * dst, char * src)
{
char * aux = dst;
while(*dst++ = *src++);
return aux;
}
At each iteration, src++ is processed first and, being a postfix increment, it returns the old value of src. Then, the old value of src (which is a pointer) is dereferenced to be assigned to whatever is in the left side of the assignment operator. The dst is then incremented and its old value is dereferenced to become an lvalue and receive the old src value. This is why dst[0] = src[0], dst[1] = src[1] etc, up until *dst is assigned with 0, breaking the loop.
Addendum:
All the code in this answer was tested with C language. In C++ you probably won't be able to list-initialize the pointer. So, if you want to test the examples in C++, you should initialize an array first and then degrade it to a pointer:
char w[] = {'a', 'c'};
char * x = w;
char y = *x++; //or the other cases
char z = *x;