views:

92

answers:

10

I have a range of memory to parse. If I find a certain sequence of bytes before the end, I interrupt the iteration. I wonder which loop I should prefer here:

while(i < end && !sequenceFound ) {
    // parse
    i++;
}

Or

for( i; i < end && !sequenceFound; i++ ) {
    // parse
}

This is used in a method of a class that derives from a class that implements a ring buffer. The superclass provides i and end. My question is, which one do you think is easier to understand (expresses the intend better) for someone unfamiliar with the code?

Edit The fact that I found the sequence is needed for the further parsing of the stream. I could use break and set sequenceFound = true, but that would be redundant, or am I being to strict here?

+1  A: 

I favour while here as that reads better. Might be a personal preference though. until which is available in some languages would be good as well.

willcodejavaforfood
+3  A: 

For an iteration that has an explicit limit, I would normally use a for loop. While loops should be used when the iteration has no upper limit.

DeadMG
A: 

The second version is better for understanding and allows to use continue operator.

Alex Farber
+6  A: 

Why not just use break; at the point that the need to "interrupt" the loop is encountered. This seems like the language feature that most idiomatically expresses your intent. It usually means that you can do without the extra boolean state tracking variable.

If you need to know whether the iteration terminated early you can use the condidition i != end. Either way, using the control method that is clearest would seem best and break; at the point at which you want to break seems clearest to me, whether or not you maintain an "early exit" variable. It seems redundant to carry on round the loop and test a condition that you've only just guaranteed will fail.

Charles Bailey
The variable is needed later, I edited that information to my question.
Space_C0wb0y
if that's the case I usually prefer to check after the loop for `if (i == end)` to see if I broke out of the loop
Idan K
@Space_C0wb0y: I did say usually, if you need to know whether the iteration terminated early you can use the condidition `i != end`. Either way, using the control method that is clearest would seem simple and `break` at the point at which you want to break seems clearest to me whether or not you maintain an "early exit" variable. It seems redundant to carry on round the loop and test a condition that you've only just guaranteed will fail.
Charles Bailey
@Charles: I accepted mostly due to your comment above. Would be nice if you made that part of the answer.
Space_C0wb0y
A: 

If I have more than one condition to check before each iteration I usually use a while loop.

slosd
A: 

How about

for( i; i < end; ++i){
    if( sequenceFound ){
        break;
    }
}
wheaties
+3  A: 

For loops with a loop variable and an end (i.e. for all loops that run over a range by checking i != end or i < end) I favour the for approach since this is more or less the canonical usage of for.

If you may leave the loop prematurely, break:

for(; i != end; ++i) {
    // parse
    if (sequenceFound)
        break;
}
Konrad Rudolph
+1 Using the break means you don't need a complicated end condition in the for loop. People don't really read the conditions for a for loop because they are often the same.
Thirler
A: 

Agree with Charles Bailey as once you break in the iteration, you immediatley break out of the most immediate looping structure, without having to re-evaluate a condition variable. Also, you do not need the additional condition variable, thus reducing (slightly that is) memory required for the block of code to run.

Michael
A: 

I prefer the for with the break internally.

The reason being that you can avoid ugly constructs that have to check your 'break' condition, e.g.:

for(; i != end; ++i) {

    // do stuff

    if (sequenceFound) break;

    // you don't need an 'if(!sequenceFound)' around this block of code
    // do more stuff
}

But with either the while version or the for with the condition built-in, depending of course on what you're doing, you can't so easily avoid that conditional.

sje397
+4  A: 

Prefer algorithms to hand-written loops.

#include <algorithm>

auto it = std::find(begin, end, predicate);
if (it == end)
    :-(
else
    :-)
FredOverflow