Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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
like image 868
Vivek Ranga Avatar asked Feb 20 '12 10:02

Vivek Ranga


People also ask

What is pointer pointer arithmetic with example?

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.

How do you do an arithmetic pointer?

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: == , !=

What is a pointer explain pointer arithmetic in C language?

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 -


3 Answers

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.

like image 121
jrok Avatar answered Sep 30 '22 05:09

jrok


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)

like image 39
Firedragon Avatar answered Sep 30 '22 06:09

Firedragon


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.

like image 23
Mohammad Dehghan Avatar answered Sep 30 '22 05:09

Mohammad Dehghan