Що означає термін циклу "while (true)" з "break" всередині? [зачинено]


24

Припустимо, у мене є цикл на C ++ або C #, який іде так:

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

Це зазвичай називають "нескінченною петлею". Але технічно це не безмежно - воно припиниться, коли контроль протікатиме через нього break.

Який термін для такої петлі - що має цикл "цикл назавжди" та управління "циклом"?


22
Я не думаю, що існує спеціальний термін.
ChrisF

2
Чи є якась гарантія того, що контроль коли-небудь проллється через прорив? У цьому прикладі, що, якщо condition()завжди повертається помилковим? Я б сказав, що це нескінченна петля з умовними перервами.
JohnL

1
Навіть без a breakцикл не є нескінченним ( kill, ctrl-alt-del, unplug ...). Так навіщо турбуватися з термінологічними деталями?
mouviciel

5
"Який термін?" - "Це зазвичай називається нескінченною петлею". Ось ваша відповідь саме там. Ви, очевидно, не задоволені терміном, але це не позбавляє факту опису (природних) мов. "Термін для X" - це те, що люди використовують, а не те, що їм слід використовувати.
MSalters

5
Це питання видається поза темою, оскільки це питання "назвіть цю річ". "Назвіть цю річ" - це погані запитання з тих же причин, що "ототожнюють це незрозуміле телешоу, фільм чи книгу за його персонажами чи оповіданнями" - це погані запитання: ви не можете їм Google, вони ні в якому разі не практичні, вони не допомагайте нікому іншим, і дозволяючи їм відкривати двері для задачі інших типів маргінальних питань. Дивіться blog.stackoverflow.com/2012/02/lets-play-the-guessing-game
gnat

Відповіді:


24

Вивчаючи CS, цей професор навчив нас, що існують цикли попередньої перевірки ( while(cond) {}), циклів після перевірки ( do {} while(cond);) і циклів середньої перевірки . (Можливо, я погано переклав це англійською мовою, але ви розумієте.)

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


1
Так, у Ада є таке:loop ... exit when condition; ... end loop;
Кіт Томпсон

@Keith: Дякую за підтвердження! Минуло майже 20 років, як я зробив якусь Ада.
sbi

1
Для чого це варто, я був професійним програмістом вже більше 20 років (і хобі - це довше), і я ніколи не чув цих термінів.
offby1

Щодо перекладу - я думаю, що "в", як правило, більше підходить, коли використовуються "попередньо" та "пост", наприклад, "попередній замовлення / порядок / обхід дерев замовлення".
Дуб

1
Термін, з яким я виріс, був "цикл середнього виходу". Я працював на декількох різних мовах з явною підтримкою циклів середнього виходу.
mjfgates

13

Перший курс з КС у Стенфорді ( Методика програмування Мехран Сахамі ) відноситься до цього як до півтора циклу . І це не обов'язково погана практика програмування. Розглянемо цей приклад збору даних користувачів (взяті з Еріка Робертса "The Art and Science of 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
}

10

Не маючи офіційного імені, я б назвав це " Зламана петля" . Неоднозначність цього терміна призначена, оскільки перерва в середині циклу трохи нечиста, майже як а goto.


Я б сказав, набагато гірше, ніж гото. Я швидше побачив би гото, ніж хибно побудований стан у такому циклі.
Брайан Кноблауш

14
@Brian Що? "Справжня" умова робить це очевидним і подібні петлі є дійсно поширеними. Наприклад, якщо ви хочете додати кожний рядок файлу до списку, вам потрібно спробувати прочитати рядок (зробити щось), зупинити, якщо він не вдався (якщо умова порушився), в іншому випадку додайте його до списку та повторіть (зробіть щось інше).
Крейг Гідні

7
З розривом посередині петлі немає нічого поганого. Якщо вам потрібно виконати якусь операцію на кожному запуску циклу, вам доведеться або дублювати код, або вводити ці операції в умову. Будь-який варіант явно має недоліки. gotoтакож були дійсні програми, наприклад, емуляція спроби ... нарешті блокувати в C.
Малькольм

1
Малькольм: Можлива проблема полягає в тому, що під час читання коду важче зрозуміти, коли і чому цикл виходить. Додаткові проблеми виникають, коли ви вкладете дві або більше таких петель і хочете вирватися із зовнішньої петлі, виходячи з умови, що знаходиться у внутрішній петлі.
користувач281377

Скажімо , у вас є цикл подій водіння додатки Xorg, як (в псевдокоді :) while(XEventGet(&ev) != NULL){ ... }, ви , природно , будете хотіти , щоб перевірити ключі всередині циклу: if(ev.key == XK_q) break;. Виконуючи наступні дії: while(XEventGet(&ev) != NULL && ev.key != XK_q){ ... }важко читати важко і, мабуть, важче, ніж розрив середньої петлі. Плюс, що робити, якщо що-небудь потрібно зробити зі значенням спочатку, перш ніж його можна перевірити? Ви не серйозно збираєтеся все це забити в базовий корпус петлі, чи не так?
Бреден Кращий

8

Немає остаточної назви. Нескінченна петля - це, я думаю, відповідний термін. Жодні петлі не є справді нескінченними, але це може бути безмежно ефективним, оскільки цілком можливо, що гілка, що містить розрив, ніколи не виникне.

Якщо ви скажете комусь "створити нескінченний цикл, і використовуйте перерву для умови X", і вони дізнаються, що ви маєте на увазі. Якщо хтось переглядає ваш код і не каже нічого, крім "мені не подобається нескінченний цикл, про який ви написали", ви дізнаєтесь, про що вони говорять (якщо, звичайно, у вас їх більше, ніж один).


1
Це не нескінченна петля; у нього чітко визначена умова завершення, як і у звичайного whileциклу, і те, як ви докажете припинення, точно такий же (пошук монотонно-зменшуваної метрики - чудовий початок).
Дональні стипендіати

8

Це цикл виконання часу з умовним в неправильному місці.


2
Так, слід писати: while (Keep_going) {doSomething (); if (умова) {Keep_going = false; } else {doSomethingElse (); }}
Стівен Гросс

10
так що ... ви говорите, що якщо ви викладаєте курс з комп’ютера і хочете описати це, ви б сказали: "а тепер ми дізнаємось про цикл * do-while з умовною умовою в неправильному місці "? Це більше схоже на релігійну думку, а не на ім'я.
Брайан Оуклі

5
@StephenGross Цей фрагмент коду - жахлива пропозиція. Refactor, щоб поставити фактичне стан у визначення циклу, або просто використовувати breakабо continue. Уникайте цінностей дозорних будь-якою ціною, вони просто черговий умовний стан, який слід подумки відслідковувати, що маскує мету коду.
Ізката

2
Сентинальні значення - затримка гото.
Вінстон Еверт

2
-1 за те, що є віні з одним виходом.
Стипендіати доналу

6

Я б проголосував за "безумовний цикл" , подібний до "безумовного стрибка". Він точно ілюструє те, що відбувається (код циклу беззастережно), без брехні (на відміну від "нескінченного циклу").


1
Але він має умови припинення; що if/ breakпосередині - частина візерунка.
Стипендіати доналу

5

Який термін для такої петлі - що має цикл "цикл назавжди" та управління "циклом"?

Це нескінченна петля з умовою розриву.

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


1
Це зовсім не безмежно; точка, в якій перевіряється умова припинення, знаходиться просто в іншому місці.
Дональні стипендіати

5

У Розетт-коді цей конкретний візерунок описаний як цикл "N плюс одна половина" . Хоча це не мій улюблений термін, це не страшно і, очевидно, є візерунком, який корисний для деяких видів петель. (Альтернативними варіантами є дублювання коду перед умовою - потенційно складно в реальних програмах - або збільшення глибини введення коду після умови, додаючи змінну умови циклу; ні це не покращує ремонтопридатність та зрозумілість коду . Єдиною причиною відхилення таких конструкцій є те, якщо потрібно наполягати на написанні циклів, щоб бути breakвільним.)


4

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

Цей цикл використовується, коли ви хочете розірвати лише після виконання деякої частини циклу в останній раз (тобто часткове виконання). Він використовується, коли ви не знайдете підходящої ситуації, коли, можливо, захочете розірвати весь цикл .

У цьому випадку потрібно перервати цикл, принаймні, виконавши doSomething()один останній раз.


2

Я маю згоду зі sbi тут - мені подобається термін циклу середньої перевірки . Цей вид конструкції був більш популярним, коли Структурне програмування почало прокручуватися, і багато мов мали для них синтаксичну підтримку.

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

У вашому конкретному випадку ваш цикл є рівнозначним

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

тож я використовував би breakверсію лише в тому випадку, якщо doSomethingабо doSomethingElseвключав декілька висловлювань, і я краще не ставлю їх на окремі функції, як ви.

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


1

Я думаю, якщо ми спробуємо скласти термін для цього, можливо:

Петля, що утечується


-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)цикл з перервою і продовжувати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.