Как лучше написать этот цикл? - PullRequest
17 голосов
/ 10 июля 2010

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

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

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

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

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

Ответы [ 6 ]

43 голосов
/ 10 июля 2010

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

do {

  knockOnDoor();

} while (doorIsLocked());

openDoor();

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

Смотри также


Петли до и после теста

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

Паскаль имеет цикл repeat-until, который также является циклом "после теста"; он зацикливается, пока условие false, и завершается сразу же, как только true.

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

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

Ссылки

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

5 голосов
/ 10 июля 2010

Вот вы:

while(knockOnDoor(),doorIsLocked());
3 голосов
/ 10 июля 2010

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

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

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

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

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

1 голос
/ 10 июля 2010

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

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

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

0 голосов
/ 07 октября 2015

Возможное решение это

for( ; doorIsLocked(); knockDoor() )

но вы также можете попробовать это

for( ; doorIsLocked();  ){
    knockDoor();
}
0 голосов
/ 10 июля 2010

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

#define WAITING_TIME 2000 //2 Seconds are enough waiting time for another knock
while(doorIsLocked()){
knockOnDoor();
//Now wait
Sleep(WAITING_TIME);
}
openDoor();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...