Как называется «while (true)» цикл с «break» внутри? [закрыто]

24

Предположим, у меня есть цикл в C ++ или C #, который выглядит следующим образом:

while( true ) {
    doSomething();
    if( condition() ) {
        break;
    }
    doSomethingElse();
}

Это обычно называют «бесконечным циклом». Тем не менее, он не является технически бесконечным - он остановится, как только контроль пройдет break.

Как называется такой цикл - в нем есть оператор управления циклом «цикл навсегда» и «разрыв» внутри?

Sharptooth
источник
22
Я не думаю, что есть специальный термин.
ChrisF
2
Есть ли гарантия, что контроль когда-либо будет проходить через разрыв? В этом примере, что, если condition()всегда возвращает false? Я бы сказал, что это бесконечный цикл с условными разрывами.
JohnL
1
Даже без a breakцикл не является бесконечным ( kill, ctrl-alt-del, unplug ...). Так зачем беспокоиться о деталях терминологии?
Mouviciel
5
"Какой срок?" - «Это обычно называют бесконечным циклом». Это твой ответ прямо здесь. Вы явно не в восторге от этого термина, но это не отменяет того факта, что (естественные) языки являются описательными. Термин «X» - это то, что люди используют, а не то, что они должны использовать.
MSalters
5
Этот вопрос кажется не по теме, потому что это вопрос «назови эту вещь». «Назови это» - плохие вопросы по тем же причинам, по которым «идентифицируют это неясное телешоу, фильм или книгу по его персонажам или истории» - это плохие вопросы: их нельзя гуглить, они не практичны, они не помогать никому другому, и разрешение им открывает дверь для того, чтобы задавать другие виды второстепенных вопросов. См blog.stackoverflow.com/2012/02/lets-play-the-guessing-game
комара

Ответы:

24

Изучая CS, этот профессор научил нас, что есть циклы предварительной проверки ( while(cond) {}), циклы последующей проверки ( do {} while(cond);) и циклы средней проверки . (Я мог бы плохо перевести это на английский, но вы поняли.)

C и C ++ не имеют последних (ISTR Ada, BICBW), поэтому ваша конструкция используется для этого в C и C ++.

SBI
источник
1
Да, у Ады есть это:loop ... exit when condition; ... end loop;
Кит Томпсон
@Keith: Спасибо за подтверждение! Прошло почти 20 лет с тех пор, как я сделал немного Ады.
ВОО
1
Что бы это ни стоило, я был профессиональным программистом уже более 20 лет (и хобби больше, чем это), и я никогда не слышал этих терминов.
offby1
Что касается перевода - я думаю, что «in» обычно более уместно, когда используются «pre» и «post», например, «обход дерева предзаказа / postorder / inorder».
Дуб
1
Термин, с которым я вырос, был «петля среднего выхода». Я работал на нескольких разных языках с явной поддержкой циклов среднего выхода.
mjfgates
13

Самый первый курс по CS в Стэнфорде ( Методология программирования Мехрана Сахами ) называет это циклом с половиной . И это не обязательно плохая практика программирования. Рассмотрим этот пример по сбору пользовательского ввода (взято из книги «Искусство и наука о Java» Эрика Робертса , где Робертс также называет это « петлей с половиной» ):

prompt user and read in the first value
while (value != sentinel) {
    process the data value
    prompt user and read in a new value
}

И затем то же самое было решено с использованием цикла с половиной идеи, чтобы избежать дублирования кода:

while (true) {
    prompt user and read in a value
    if (value == sentinel) break;
    process the data value
}
ernes7a
источник
10

Не имея официального названия, я бы назвал его « Сломанная петля» . Предполагается неоднозначность этого термина, поскольку разрыв в середине цикла немного нечист, почти как a goto.

user281377
источник
Я бы сказал, гораздо хуже, чем Гото. Я бы предпочел увидеть goto, чем ложно построенное условие в такой петле.
Брайан Кноблаух
14
@ Брайан Что? «Истинное» условие делает это очевидным, и подобные циклы действительно распространены. Например, если вы хотите добавить каждую строку файла в список, вы должны попытаться прочитать строку (что-то сделать), остановить, если она не удалась (если условие нарушается), в противном случае добавить ее в список и повторить (сделать что-то). еще).
Крейг Гидни
7
Нет ничего плохого в разрыве в середине цикла. Если вам нужно выполнить какую-либо операцию при каждом запуске цикла, вам придется либо дублировать код, либо вставить эти операции в условие. У каждого варианта есть свои недостатки. gotoтакже были действительные приложения, например, эмуляция блока try ... finally в C.
Малкольм
1
Малькольм: Возможная проблема заключается в том, что во время чтения кода сложнее понять, когда и почему выход из цикла. Дополнительные проблемы возникают, когда вы вкладываете два или более таких циклов и хотите выйти из внешнего цикла на основе условия, найденного во внутреннем цикле.
user281377
Скажем , у вас есть цикл событий вождения приложения Xorg, как (в псевдокоде :) while(XEventGet(&ev) != NULL){ ... }, вы , естественно , будете хотеть , чтобы проверить ключи внутри цикла: if(ev.key == XK_q) break;. Делать следующее: while(XEventGet(&ev) != NULL && ev.key != XK_q){ ... }уродливо и, возможно, труднее для чтения, чем разрыв в середине цикла. Кроме того, что, если что-то нужно сделать со значением, прежде чем его можно будет проверить? Ты же не собираешься всерьез вставлять все это в базовый вариант цикла?
Брэден Бест
8

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

Если вы скажете кому-то «создать бесконечный цикл и использовать разрыв для условия X», и они поймут, что вы имеете в виду. Если кто-то просматривает ваш код и говорит не что иное, как «мне не нравится бесконечный цикл, который вы написали», вы поймете, о чем он говорит (если, конечно, у вас их больше одного).

Брайан Оукли
источник
1
Это не бесконечный цикл; у него есть четко определенное условие завершения, как в обычном whileцикле, и способ подтверждения завершения точно такой же (поиск монотонно убывающей метрики - отличное начало).
Donal Fellows
8

Это цикл с условным заданием в неправильном месте.

Malfist
источник
2
Да, это должно быть написано: while (keep_going) {doSomething (); if (условие) {keep_going = false; } else {doSomethingElse (); }}
Стивен Гросс
10
так что ... вы говорите, что если вы преподаете компьютерный курс и хотите описать это, вы бы сказали "и теперь мы собираемся узнать о цикле * do-while с условным в неправильном месте «? Это больше похоже на религиозное мнение, чем на имя.
Брайан Оукли
5
@StephenGross Этот фрагмент кода - ужасное предложение. Рефакторинг, чтобы поместить фактическое условие в определение цикла, или просто использовать breakили continue. Избегайте дозорных значений любой ценой, это просто еще одна произвольная часть состояния, которую нужно мысленно отслеживать, которая маскирует цель кода.
Изката
2
Сентинные значения являются задержанными значениями.
Уинстон Эверт
2
-1 за то, что ты единоличный выход.
Донал Феллоуз
6

Я бы проголосовал за «безусловный цикл» , похожий на «безусловный переход». Он иллюстрирует, что именно происходит (код выполняется без каких-либо условий), не обманывая (в отличие от «бесконечного цикла»).

tdammers
источник
1
Но у него есть условие завершения; это if/ breakв середине является частью шаблона.
Donal Fellows
5

Как называется такой цикл - в нем есть оператор управления циклом «цикл навсегда» и «разрыв» внутри?

Это бесконечный цикл с условием разрыва.

Я согласен с ammilind в том, что если вы хотите дать ему специальное имя, вы можете назвать его бесконечной частичной петлей

Ramhound
источник
1
Это совсем не бесконечно; точка, где проверяется условие завершения, находится просто в другом месте.
Donal Fellows
5

В коде Розетты этот конкретный шаблон описывается как цикл «N плюс одна половина» . Хотя это не мой любимый термин, он не ужасен и, несомненно, является шаблоном, который полезен для некоторых типов циклов. (Альтернативой является дублирование кода «до условия», что может быть сложно в реальных программах, или увеличение глубины вложения кода после условия при добавлении переменной условия цикла; ни улучшается удобство сопровождения или понятность кода Единственная причина отклонения таких конструкций - если кто-то настаивает на написании циклов, чтобы быть breakсвободными.)

Donal Fellows
источник
4

Стандартного термина нет, но я бы сказал, что это частичный цикл .

Этот цикл используется, когда вы хотите разорвать только после выполнения какой-то части цикла в последний раз (то есть частичное выполнение). Он используется, когда вы не находите подходящую ситуацию, когда вы можете разорвать весь цикл .

В этом случае вы хотите разорвать цикл после хотя бы doSomething()одного выполнения в последний раз.

iammilind
источник
2

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

Тем не менее, в настоящее время широко известно, что whileциклы, как правило, более управляемы, так как об инвариантах легче рассуждать, и они часто лучше справляются с хитрым пустым случаем.

В вашем конкретном случае ваш цикл просто эквивалентен

for(; doSomething(), !condition(); doSomethingElse()){}

поэтому я хотел бы использовать только breakверсию , если либо doSomethingили doSomethingElseпривлеченные несколько операторов , и я предпочел бы не убрать их на отдельные функции , как вы делали.

Тем не менее, если ваш цикл более сложный, чем итерация (начало, проверка, приращение), то вам следует рассмотреть возможность его реорганизации в нечто более простое.

hugomg
источник
1

Я думаю, если мы собираемся попытаться придумать термин для этого, может быть:

Спасаемая петля

LarsTech
источник
-1. вопрос не в том, чтобы придумать имя, а в том, существует ли уже общее имя. Кроме того, все циклы "экранируемые", поэтому это не особенно эффективное имя.
Брайан Оукли
@BryanOakley Бесконечный цикл по определению не должен разрываться. Вероятно, не должно быть термина для этого, кроме плохого программирования.
LarsTech
0

Это не так плохо в каждом случае. Я пишу такие циклы с определенными API-интерфейсами. Скажем, например, что у вас есть объект цикла, и вам нужно проверить какое-то условие достаточно глубоко в нем, например:

while (loop
    .getAExecutionModelFactory()
    .getActiveXexecutor()
    .getYCancelModelHandler()
    .getCurrentHandler()
    .isCancelled()) {
        // ... do something with the current Handler ....
        loop = ..... // prepare for next loop
}

Теперь предположим, что каждый метод getXXX потенциально может возвращать ноль. Тогда можно было бы написать логическое выражение, хотя и довольно сложное и нечитаемое. И затем мы должны повторить почти то же самое, чтобы получить текущий объект-обработчик. В таких случаях мне легче написатьwhile (true) цикл с break и продолжить.

Инго
источник