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
When a pointer is incremented, it actually increments by the number equal to the size of the data type for which it is a pointer. For Example: If an integer pointer that stores address 1000 is incremented, then it will increment by 2(size of an int) and the new address it will points to 1002.
p = p + 2; If you have two pointers that point to the same array, you can subtract one pointer from the other. This operation yields the number of elements in the array that separate the two addresses that the pointers refer to. You can compare two pointers with the following operators: == , !=
A pointer in c is an address, which is a numeric value. Therefore, you can perform arithmetic operations on a pointer just as you can on a numeric value. There are four arithmetic operators that can be used on pointers: ++, --, +, and -
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.
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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With