Как лучше написать этот цикл?
У меня есть код, который делает что-то вроде этого:
while (doorIsLocked()) {
knockOnDoor();
}
openDoor();
но я хочу быть вежливым и всегда стучать в дверь, прежде чем открывать его.
Я могу написать что-то вроде этого:
knockOnDoor();
while (doorIsLocked()) {
knockOnDoor();
}
openDoor();
но мне просто интересно, есть ли более совершенная идиома, которая не повторяет утверждение.
Ответы
Ответ 1
Вы можете использовать do-while
вместо цикла while-do
:
do {
knockOnDoor();
} while (doorIsLocked());
openDoor();
В отличие от цикла while-do
, do-while
выполняет тело один раз перед проверкой условия завершения.
См. также
Предварительные и посттестные циклы
Цикл do-while
- иногда называемый просто оператором do
- в C/С++/С#/Java/некоторые другие - это так называемый цикл post-test: условие завершения завершается после каждая итерация. Он завершает while
условие true
, заканчивая сразу же после false
.
Pascal имеет цикл repeat-until
, который также является циклом "посттест"; он зацикливается, пока условие false
, заканчивается сразу же после true
.
Контур Fortran do-while
, с другой стороны, представляет собой цикл "pre-test": условие завершения завершается перед каждой итерацией. В C/С++/Java/С#/некоторые другие, циклы while-do
и for
также являются "пред-тестовыми" циклами.
Всегда проверяйте ссылку на язык, если вы сомневаетесь.
Ссылки
Связанные вопросы
Ответ 2
Здесь вы находитесь:
while(knockOnDoor(),doorIsLocked());
Ответ 3
@polygenelubricants уже опубликовали очевидное лучшее решение для этого.
В некоторых случаях, однако, может быть проще удалить условие из цикла целиком и сделать что-то вроде этого:
for (;;) {
knockOnDoor();
if (!doorIsLocked()) { break; }
}
так как он дает вам полный контроль над тем, что делать до и после условия цикла.
Но когда a do-while
делает то, что вам нужно, определенно предпочитайте это.
Ответ 4
Вы можете сделать рекурсивный вызов:
void openLockedDoor(){
knockOnDoor();
if( doorIsLocked() ){
return openLockedDoor();
}
return openDoor();
}
но do-while
выше работает так же хорошо (или даже лучше, в зависимости от вашего компилятора).
Ответ 5
Ты забыл подождать... Если ты продолжаешь стучать, это тоже будет невежливо... поэтому лучший способ - сделать это вот так:
#define WAITING_TIME 2000 //2 Seconds are enough waiting time for another knock
while(doorIsLocked()){
knockOnDoor();
//Now wait
Sleep(WAITING_TIME);
}
openDoor();
Ответ 6
Возможным решением является
for( ; doorIsLocked(); knockDoor() )
но вы также можете попробовать это
for( ; doorIsLocked(); ){
knockDoor();
}