Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subtracting pointers

Tags:

c++

pointers

I have been asked to describe what these lines of code are doing for a college assignment

int main() {     int t1[] = {0,0,1,1,1}, t2[] = {0,0,1,1,1};     int *p1 = t1, *p2 = t2;      while (!*p1++ || !*p2++);     cout << (p1-t1) << endl;     cout << (p2-t2) << endl; } 

My take on it is, 2 arrays of type int are created and filled with values, 2 pointers are created and pointed at each array, then I start to have trouble.

while (!*p1++ || !*p2++); 

To me this is saying while 0 move the position of *p1one place or while 0 move the position of *p2 one place, I'm really not confident in that assumption?

cout << (p1-t1) << endl; 

So then we move onto the cout, now my take on this is, I'm subtracting the position of p1 from the position of t1, where p1 was positioned by the while and t1 points to the first position in the array. again I could be completely wrong I'm only learning about pointers so please bear this in mind if I'm wrong in my assumptions.

like image 371
JTK Avatar asked Oct 14 '14 16:10

JTK


People also ask

Can I subtract two pointers?

The subtraction of two pointers is possible only when they have the same data type. The result is generated by calculating the difference between the addresses of the two pointers and calculating how many bits of data it is according to the pointer data type.

Why is adding two pointers impossible?

Pointers contain addresses. Adding two addresses makes no sense, because you have no idea what you would point to. Subtracting two addresses lets you compute the offset between these two addresses, which may be very useful in some situations.


1 Answers

The while loop is actually quite horrid. I've never seen code like this in real life, and would declare any programmer doing it in real life as mad. We need to go through this step by step:

while (condition); 

We have here a while statement with an empty statement (the ";" alone is an empty statement). The condition is evaluated, and if it is true, then the statement is executed (which does nothing because it is an empty statement) and we start all over again. In other words, the condition is evaluated repeatedly until it is false.

condition1 || condition2 

This is an "or" statement. The first condition is evaluated. If it is true, then the second condition is not evaluated and the result is "true". If it is false, then the second condition is evaluated, and the result is "true" or "false" accordingly.

while (condition1 || condition2); 

This evaluates the first condition. If it's true we start all over. If it is false, we evaluate the second condition. If that is true, we start all over. If both are false, we exit the loop. Note that the second condition is only evaluated if the first one is false. Now we look at the conditions:

!*p1++ !*p2++ 

This is the same as *(p1++) == 0 and *(p2++) == 0. Each condition increases p1 or p2 after it has been evaluated, no matter what the outcome. Each condition is true if *p1 or *p2 was zero and false otherwise. Now we check what happens at each iteration:

p1 = &t1 [0], p2 = &t2 [0] *p1++ == 0 is true, *p2++ == 0 is never evaluated, p1 = &t1 [1], p2 = &t2 [0]. *p1++ == 0 is true, *p2++ == 0 is never evaluated, p1 = &t1 [2], p2 = &t2 [0]. *p1++ == 0 is false, *p2++ == 0 is true, p1 = &t1 [3], p2 = &t2 [1]. *p1++ == 0 is false, *p2++ == 0 is true, p1 = &t1 [4], p2 = &t2 [2]. *p1++ == 0 is false, *p2++ == 0 is false, p1 = &t1 [5], p2 = &t2 [3]. 

t1 is the same as &t1 [0]. p1 - t1 == &t1 [5] - &t1 [0] == 5. t2 is the same as &t2 [0]. p2 - t2 == &t2 [3] - &t2 [0] == 3.

like image 166
gnasher729 Avatar answered Sep 20 '22 15:09

gnasher729