简体   繁体   English

再执行一次 while 循环的标准用法

[英]Standard idiom for executing a while loop one more time

Is there a pattern in C to execute a while loop one more time. C 中是否有一种模式可以再执行一次 while 循环。 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.如果进程是多行而不是单个 function 调用,那将是可怕的。

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注意:do while 循环不是解决方案,因为它等同于

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.我想从 another_buffer 填充缓冲区并将 (indexof(next_set_bit) + 1) 放入 MSB,同时保持掩码和指针。

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);

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. 我并不是说这是一个标准的习惯用语,只是一个临时的黑客。

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. 只要condition为真,循环就会执行,然后再循环一次,如果循环开始时condition为假,则循环为零。 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. 如果没有,并且你总是希望循环至少执行一次,那么do...while你正在寻找的成语。

I'd use this: 我用这个:

bool done = false;
do {
  if (!condition) done = true;
  condition = process();
} while (!done);

A much less readable hack, assuming condition is not predefined: 一个不太可读的黑客,假设condition未预定义:

for (bool condition=true, done=false;
     !done && (condition || done = true);
    ) {
  condition = process();
}

I've had this same issue and my solution is: 我有同样的问题,我的解决方案是:

Only if you know for sure you want to run process() at least once: 只有当您确定要至少运行一次process()时:

while(1){
    process();
    if(!condition()) break;
    /*The loop breaks before bad things happen*/
    things_you_want_to_happen_only_while_condition_is_true();
}

If you are not sure: 如果您不确定:

if(condition()){ /*Same as before, but it checks first*/
    while(1){
        process();
        if(!condition()) break;
        /*The loop breaks before bad things happen*/
        things_you_want_to_happen_only_while_condition_is_true();
    }
}

For example: 例如:

/*A pointer that goes over the string T from right to left.
It prints "Yes" when pointing at the character 'O' and "No" when not*/
char T[] = {'O', 'V', 'E', 'R', 'F', 'L', 'O', 'W', 0};
char *P = &T[strlen(T)-1]; /*We want the pointer to start at the last character of T*/
while(1){
    if(*P=='O') printf("Yes\n");
    else printf("No\n");
    if(P==&T[0]) break; /*When it reaches the beginning of T, it stops*/
    /*We only want the pointer to go further back if it is not in the beginning of T.
    That's because we don't know what's before in the memory.*/
    P--;
}

Your code is way more advanced than my level, but I came to this question as I had a similar difficulty on a problem set (I wanted the function to execute one last time) and I solved it like this:你的代码比我的水平更高级,但我遇到了这个问题,因为我在问题集上遇到了类似的困难(我希望 function 最后一次执行)并且我这样解决了它:

define check_value as type_required;

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

Would something like that work?这样的事情行得通吗? In my problem I'm just taking a modulus so I can just run the process twice, system overhead really isn't a consideration.在我的问题中,我只是取一个模数,这样我就可以运行这个过程两次,系统开销真的不是一个考虑因素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM