Vivek Ranga
Vivek Ranga

Reputation: 75

Pointer to pointer Arithmetic

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

Answers (5)

Firedragon
Firedragon

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

jrok
jrok

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

Moha Dehghan
Moha Dehghan

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

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

Francesco Boffa
Francesco Boffa

Reputation: 1402

++*p is executed before printing. So increment pointer, then print. *p++ is executed after printing. Print, then increment.

Upvotes: 0

Related Questions