Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Standard idiom for executing a while loop one more time

Is there a pattern in C to execute a while loop one more time. Currently I'm using

while(condition) {
    condition = process();
    // process() could be multiple lines instead of a function call
    // so while(process());process(); is not an option
}
process();

which is horrible if process is of multiple lines and not a single function call.

The alternative is

bool run_once_more = 1;
while(condition || run_once_more) {
    if (!condition) {
        run_once_more = 0;
    }
    condition = process();
    condition = condition && run_once_more;
}

Is there a better way?


Note: A do while loop is not a solution as it is equivalent to

process();
while(condition){condition=process();}

I want

while(condition){condition=process();}
process();

Per requests, a bit more specific code. I want to fill buffer from another_buffer and get (indexof(next_set_bit) + 1) into MSB while maintaining both masks and pointers.

uint16t buffer;
...
while((buffer & (1 << (8*sizeof(buffer) - 1))) == 0) { // get msb as 1
    buffer <<= 1;
    // fill LSB from another buffer
    buffer |= (uint16_t) (other_buffer[i] & other_buffer_mask);
    // maintain other_buffer pointers and masks
    other_buffer_mask >>= 1;
    if(!(other_buffer_mask)) { 
        other_buffer_mask = (1 << 8*sizeof(other_buffer[0]) -1)
        ++i;
    }
}
// Throw away the set MSB
buffer <<= 1;
buffer |= (uint16_t) (other_buffer[i] & other_buffer_mask);
other_buffer_mask >>= 1;
if(!(other_buffer_mask)) { 
    other_buffer_mask = (1 << 8*sizeof(other_buffer[0]) -1)
    ++i;
}
use_this_buffer(buffer);
like image 728
user80551 Avatar asked Apr 06 '15 16:04

user80551


Video Answer


2 Answers

Because it's not a very typical thing to do, it's unlikely that there is a standard idiom for doing this. However, I'd write the code like this:

for (bool last = 0; condition || last; last = !(condition || last)) {
    condition = process();
}

The loop will execute as long as condition is true and then one more time, or zero times if condition is false when the loop begins. I interpret your question as meaning that that is the desired behavior. If not, and you always want the loop to execute at least once, then do...while is the idiom you seek.

like image 164
Edward Avatar answered Sep 28 '22 03:09

Edward


What about this:

int done, condition = 1;
for (;;) {
    ...
    done = !condition;
    condition = process();
    if (done) break;
    ...
}

I am not suggesting this is a standard idiom, just an ad hoc hack.

like image 27
chqrlie Avatar answered Sep 28 '22 04:09

chqrlie