Thu
01
Mar 2012
I've had a discussion recently with my colleagues about what is the best way of writing a loop in C++ that would iterate backward: Count-1, Count-2, ..., 0, using unsigned integer numbers. I'd like to share all possible solutions I managed to gather.
Iterating forward is simple:
unsigned count = 10;
// Forward: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
for(unsigned i = 0; i < count; ++i)
printf("%d ", i);
Iterating backward is equally simple and looks similar, if you use signed integers:
// Backward: 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
// Using signed integer
for(int i = count - 1; i >= 0; --i)
printf("%d ", i);
Same code cannot be used with unsigned integers, because it creates infinite loop, as unsigned number is always >= 0 and just wraps around to maximum value 0xFFFFFFFF:
// WRONG: Inifinte loop, unsigned int wraps around and is always >= 0.
for(unsigned i = count - 1; i >= 0; --i)
printf("%d ", i);
Changing condition to i > 0 is also invalid, because then loop is not executed for i == 0:
// WRONG: Not executed for i == 0.
for(unsigned i = count - 1; i > 0; --i)
printf("%d ", i);
Here comes a bunch of possible valid solutions. My favourite is following for loop:
for(unsigned i = count; i--; )
printf("%d ", i);
Following while loop does same thing. Some people say that it looks more clear. I don't think so, while I believe the for loop is better because it creates local scope for variable i, while the following code does not:
unsigned i = count;
while(i--)
printf("%d ", i);
Another way of implementing exactly same logic is to write the condition like this. It may look like C++ had the "goes to zero" arrow operator -->, but it is actually just (i-- > 0) :)
unsigned i = count;
while(i --> 0)
printf("%d ", i);
Another possible solution of loop condition (a one that does not use the postdecrementation operator) is to compare i with maximum integer value. One disadvantage of it is that you have to carefully match the value of the max constant with type of your iterator - whether it is unsigned int, unsigned short etc.
for(unsigned i = count - 1; i != UINT_MAX; --i)
printf("%d ", i);
Another way of doing this, without using maximum value, is:
for(unsigned i = count - 1; i < count; --i)
printf("%d ", i);
Finally there are solutions possible that introduce second iterator:
// Option 1 using second iterator:
// i goes 0...9, j is inverted i.
for(unsigned i = 0; i < count; ++i)
{
unsigned j = count - i - 1;
printf("%d ", j);
}
// Option 2 using second iterator:
// i goes 10...1, j is decramented i.
for(unsigned i = count; i > 0; --i)
{
unsigned j = i - 1;
printf("%d ", j);
}
Which is your favorite loop? Please leave a comment :)
Comments | #algorithms #c++ Share