Pointer to array, while loop on data

Hi there,

I have some code that I would like to understand a bit better. I understand that 2 arrays (t1 and t2) are created, then 2 pointers (p1 and p2) to the arrays are created. Although I would appreciate it if someone could explain what the rest of the code does (the last 3 lines).

1
2
3
4
5
6
7
8
9
  void 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;
}


console output = 5 3 (I have no idea how)
Last edited on
That's a sort of obfuscating crap code which no one want to see in the wilderness, merely good for teaching proposes.

But lets see what happens:

At line 4 there will be set two pointers, each of the starting-address of the arrays. Now the interesting while-loop:
The while loop consists of two parts, conectet with an or which means if any of the parts get true, then the while loop will executed. But at || the evaluation of the while header aborts if any of the two parts get true, because then the other part doesen't matter, it's meaningless if it would be true or false.
So at the first loops only the first part will be executed because it will get evaluated to true. Later, when the first part will get false, both parts will get evaluated. This goes so long until both parts will evaluated to false.

Here the explaination how the parts get evaluated:
Therefore we need to know what execution order will proceed. This depends on the operator precedence.
Both the * and the ++ have the same precedence, so it will evaluated from left to right. Then we have the ! with lower precedence order.
The * returns the value of the address which it points. After that it gets evalued by the !, which checks if the value is 0. At least, the pointer's address will get incremented by one.

So at the first two while loops the left part get evaluated to 0. At the 3rd loop it will get evaluated to false, because !1 is false. Since this evaluation turn the 2nd part of the while loop needs get evaluated too. And the loop will abort if both terms get evaluated to false. Then p1 would have been 5 times increased and the p2 got 3 times.

The last parts (p1 - t1) are pointer arithmetic. There will get evaluated which distance the pointer addresses to the arrays have. Be aware that this distance before the while loop is 0.
Last edited on
In the while statement notice the *p1++, the ++ stands for post increment operator. Which means the pointer is incremented once AFTER the while statement.

In c++ variables themselves can also evaluate to true or false depending on their values. In this case if the pointer points to nothing, the expression is evaluated to false.

So the first cout statement is executed while both p1 and p2 have value because of LOGICAL NOT. ;)

God its hard to type on my phone..
All the loop does is increment p1 and p2. The complexity comes from the short-circuit operation of the logical OR operator. The increment of p1 happens every iteration, but the increment of p2 only happens if p1 doesn't point to a zero (!*p1 is false). In that case, p2 will be (post-) incremented and will be the determining factor in whether the loop continues, although since p1 is incremented every time it could hit a zero and again short-circuit p2's increment once again. The loop stops when they both point to non-zeroes.

This is a strangely complex behavior and I'm not sure what it's modeling. Does this code have a purpose or is it just supposed to be confusing?

Anyway, the loop iterates 5 times, so that's why p1 is incremented 5 times (p1 - t1 == 5). But p2 is only incremented once p1 gets past the initial two zeroes, so p2 is only incremented 3 times. Basically, it ends when p1 points to its last 1 and p2 points to its first 1, and due to the post-increment they are both moved one more position.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
using namespace std;

void prn(int *t1, int *t2, int *p1, int *p2) {
    cout << p1-t1 << ':' << *p1 << "    "
         << p2-t2 << ':' << *p2 << '\n';
}

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



0:0    0:0
1:0    0:0
2:1    0:0
3:1    1:0
4:1    2:1
5      3

Last edited on
Thank you for all the very helpful replies!

@tpb: I am not quite sure why my lecturer wanted us to explain this code, maybe to give me some sort of understanding of pointer arithmetic. Thanks again for the help
Topic archived. No new replies allowed.