Как записать этот цикл лучше?

У меня есть код, который делает что-то вроде этого:

while (doorIsLocked()) {
    knockOnDoor();
}
openDoor();

но я хочу быть вежливым и всегда стучать в дверь, прежде чем я открою ее. Я могу записать что-то вроде этого:

knockOnDoor();
while (doorIsLocked()) {
    knockOnDoor();
}
openDoor();

но я просто задаюсь вопросом, существует ли лучшая идиома, которая не повторяет оператор.

17
задан BaCaRoZzo 7 October 2015 в 22:38
поделиться

5 ответов

Вы можете использовать do-while вместо цикла while-do :

do {

  knockOnDoor();

} while (doorIsLocked());

openDoor();

В отличие от while-do ] цикл do-while выполняет тело один раз перед проверкой условия завершения.

См. Также


Циклы предварительного и последующего тестирования

Цикл do-while - иногда его называют просто do ] - в C / C ++ / C # / Java / некоторых других есть так называемый цикл «пост-теста»: условие завершения проверяется после каждой итерации. Он выполняет цикл , в то время как условие истинно , немедленно завершается, как только оно ложно .

В Паскале есть цикл повторять до , который также является циклом «после проверки»; он зацикливается, пока условие ложно , и немедленно завершается, как только становится истинным .

Цикл Фортрана do-while , с другой стороны, является циклом «предварительного тестирования»: условие завершения проверяется перед каждой итерацией. В C / C ++ / Java / C # / некоторых других, while-do и for циклы также являются «предварительными» циклами.

Всегда проверяйте справочную информацию о языке, если сомневаетесь.

Ссылки

Связанные вопросы

43
ответ дан 30 November 2019 в 10:36
поделиться

Вот вы:

while(knockOnDoor(),doorIsLocked());
5
ответ дан 30 November 2019 в 10:36
поделиться

Вы можете выполнить рекурсивный вызов:

void openLockedDoor(){
    knockOnDoor();
    if( doorIsLocked() ){
        return openLockedDoor();
    }
    return openDoor();
}

, но do-while выше работает точно так же (или даже лучше, в зависимости от на вашем компиляторе.)

1
ответ дан 30 November 2019 в 10:36
поделиться

@polygenelubricants уже опубликовал очевидное лучшее решение для этого.

В некоторых случаях, однако, может быть проще полностью удалить условие из цикла и сделать что-то вроде этого:

for (;;) {
  knockOnDoor();
  if (!doorIsLocked()) { break; }
}

поскольку это дает вам полный контроль над тем, что делать до и после условия цикла.

Но когда do-while делает то, что вам нужно, определенно предпочтите это.

3
ответ дан 30 November 2019 в 10:36
поделиться

Вы забыли подождать... Если вы продолжите стучать, это будет невежливо... поэтому лучше всего сделать вот так:

#define WAITING_TIME 2000 //2 Seconds are enough waiting time for another knock
while(doorIsLocked()){
knockOnDoor();
//Now wait
Sleep(WAITING_TIME);
}
openDoor();
0
ответ дан 30 November 2019 в 10:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: