Reputation: 75
Can someone explain the output of the following code
char* a[] = {"ABC123", "DEF456", "GHI789"};
char **p = a;
cout<<++*p<<std::endl;
cout<<*p++<<std::endl;
cout<<++*p<<std::endl;
Output:
BC123
BC123
EF456
What is confusing to me is the different behavior of ++*p and *p++. I was expecting the output to be:
ABC123
DEF456
GHI789
Upvotes: 5
Views: 1583
Reputation: 3733
char* a[] = {"ABC123", "DEF456", "GHI789"};
char **p = a;
cout<<++*p<<std::endl; // 1
cout<<*p++<<std::endl; // 2
cout<<++*p<<std::endl; // 3
On line 1 first *p
will be pointing to the element in the array "ABC123"
and the ++
moves one forward and so 'BC123' is printed.
On line 2 *p
is still pointing to BC123
so this is printed and then once printed the ++
is carried out. This moves the pointer to the 2nd element in the array
On line 3 it is the same as line 1. You have taken the contents of p
(Now the 2nd element in the array) and moved one character in that string, thus printing EF456
(Also have a look at here Pointer arithmetic on string type arrays, how does C++ handle this? as I think it might be useful to get an understanding of what is happening)
To print what you expected the following would work:
cout<<*p++<<std::endl;
cout<<*p++<<std::endl;
cout<<*p++<<std::endl;
Or
cout<<*p<<std::endl;
cout<<*(++p)<<std::endl;
cout<<*(++p)<<std::endl;
Or various other ways (taking into account precedence as others have said)
Upvotes: 3
Reputation: 55395
Perhaps this will help. You example is roughly equivalent to this:
++(*p);
cout << *p << '\n';
cout << *p << '\n';
++p;
++(*p);
cout << *p << '\n';
Without parentheses, *p++
is parsed as *(p++)
since suffix increment has got higher precedence than dereference operator. Increment is still done after the whole expression, though.
On the other hand, prefix increment and * have got same precedence, so ++*p
is parsed right-to-left as ++(*p)
. Knowing that prefix increment has to be done before the expression, you can now put the whole picture together.
Upvotes: 5
Reputation: 18443
According to C++ operator precedence table, precedence of post-increment is higher than dereference (*) operator, and pre-increment and dereference operator have same precedence. Also pre-increment and dereference operator are right-to-left associative.
So in the first line (cout<<++*p<<std::endl;
), * and ++ are evaluated from right to left (first dereference, then increment). Now p
still point to the first array (because it has not changed),but (*p) points to the second letter of the first string (the output shows this fact).
In second line (cout<<*p++<<std::endl;
) however post-increment is evaluated first (after retrieving the old value of p
) and the p
is incremented and now points to the second array. But before increment, the value of p is used in the expression and output of the second line is exactly as the first line.
In third line, first the p
is dereferenced (point to the first letter of the second array), then incremented (point to the second letter of the second array), and the value is printed.
Upvotes: 1
Reputation: 21521
Just a guess, but I think because you are incrementing the deferenced pointer using cout<<++*p<<std::endl;
, what you are actually doing is incrementing the character at the start of the string that p points to then outputting this to the standard output.
Similarly cout<<*p++<<std::endl;
is incrementing the character after outputting so the final cout<<++*p<<std::endl;
results in two increments.
You should try this instead and see if it works
cout<<*(++p)<<std::endl;
cout<<*(p++)<<std::endl;
cout<<*(++p)<<std::endl;
Upvotes: 0
Reputation: 1402
++*p
is executed before printing. So increment pointer, then print.
*p++
is executed after printing. Print, then increment.
Upvotes: 0