decremented loop counter

Started by
8 comments, last by Drigovas 16 years, 10 months ago
What's the reason for this, the n-- in the while loop? Why is the -- added? while(n-- > 0) { *p1 = *p2; p1++; p2++; } [Edited by - LessBread on June 2, 2007 12:23:20 PM]
Advertisement
n-- will decrease the variable n by 1.
However there is a twist, with it being after the n it will check that the number is above 0 first then decrease its value ready for the next loop.
This is just a compact form of the following:
while ( n > 0 ) {  ...  n--;}


It is however the same as:
for ( ; n > 0; n--) {  ...}


The statement above is evaluated as:
while (  (n--) > 0 ) {}


Which can also be written just as:
while (n--) {}

But this aproach is unsafe, since it will fail for negative numbers, and works only if n is unsigned.

The exact value of n also depends on the loop. For some loops you might need to pre-decrement n before starting the loop, or you might need to compare it to something else than 0, such as -1 or 1.
Quote:Original post by markg
What's the reason for this, the n-- in the while loop? Why is the -- added?


while(n-- > 0)
{
*p1 = *p2;
p1++;
p2++;
}


What would be a better loop to use besids theis one?
Quote:Original post by markg
What's the reason for this, the n-- in the while loop? Why is the -- added?


while(n-- > 0)
{
*p1 = *p2;
p1++;
p2++;
}


What would be a better loop to use besids theis one?
Quote:Original post by markg
Quote:Original post by markg
What's the reason for this, the n-- in the while loop? Why is the -- added?


while(n-- > 0)
{
*p1 = *p2;
p1++;
p2++;
}


What would be a better loop to use besids theis one?


Why loop?

In C, memcpy(p1,p2,n * sizeof(type of p1 and p2) );

In C++, std::copy(p2,p2 + n,p1);

If this is for strings use string copying routines, such as strcpy in C and std::string's copy constructor in C++.
Quote:Original post by Antheus
This is just a compact form of the following:
while ( n > 0 ) {  ...  n--;} 


Not quite. Your version only decrements n when the body of the loop is executed. The result is that n will have a different value after the loop is done. It doesn't make a difference in this case, but it can in others.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Quote:Original post by JohnBolton
Quote:Original post by Antheus
This is just a compact form of the following:
while ( n > 0 ) {  ...  n--;} 


Not quite. Your version only decrements n when the body of the loop is executed. The result is that n will have a different value after the loop is done. It doesn't make a difference in this case, but it can in others.


I mentioned at the end of the post that the value for n depends on the type of loop used.

I tend to avoid such shortcuts, since they can often result in weird boundary conditions which might not be immediately obvious.
C-syntax allows for lots of variations and bastardisations like this, many of which have their own particular gotchas. In general, it's a good idea to keep your code readable, so this syntax is best avoided. In this case, you're (for no good reason) iterating over a section of code with a decrementing variable. To most people, this suggests the use of a for loop:

for (; n > 0; --n) {    // Do your thing}
You haven't shown us where n came from, but if it is defined shortly before, tradition would have you pull that line into the first for clause. The same goes for declaration and initialisation of temporary loop variables. So

int n = 50;while(n-- > 0){    //}
should be
for (int n = 50; n > 0; --n) {    //}
which can help you eliminate scope errors among other things. If you're wondering why I'm using the prefix decrement (--n) rather than postfix, it makes no difference in this instance, but is a good habit to get into, as postfix decrements can introduce unnecessary performance penalties for certain classes.

Admiral
Ring3 Circus - Diary of a programmer, journal of a hacker.
Quote:Original post by JohnBolton
Quote:Original post by Antheus
This is just a compact form of the following:
while ( n > 0 ) {  ...  n--;}
Not quite. Your version only decrements n when the body of the loop is executed. The result is that n will have a different value after the loop is done. It doesn't make a difference in this case, but it can in others.
You're correct about it only decrementing when the loop is run through, but
while(n-- > 0)
DOES NOT EQUAL
while(n > 0){  ...  n--;}
in this case, or likely any other.

It might equal
while(n>0){  n--;  ...}
but there is a very important distinction between these two. One the body of the loop gets executed on values between and including 1 and n, and the other between and including 0 and n-1 [which is also what is included in the processing of the original loop]. Then of course are the cases inwhich n started <= 0, which were already mentioned as trouble spots.

This topic is closed to new replies.

Advertisement