Jaki jest termin „pętla„ while ”(prawda) z„ break ”w środku? [Zamknięte]

24

Załóżmy, że mam pętlę w C ++ lub C #, która wygląda tak:

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

Jest to powszechnie nazywane „nieskończoną pętlą”. Jednak nie jest to technicznie nieskończone - zatrzyma się, gdy przepłynie kontrola break.

Jaki jest termin na taką pętlę - w której znajduje się instrukcja kontroli pętli „na zawsze” i „przerwa”?

sharptooth
źródło
22
Nie sądzę, że istnieje specjalny termin.
ChrisF
2
Czy jest jakaś gwarancja, że ​​kontrola kiedykolwiek przepłynie przez przerwę? W tym przykładzie, co jeśli condition()zawsze zwraca false? Powiedziałbym, że to nieskończona pętla z przerwami warunkowymi.
JohnL,
1
Nawet bez a break, pętla nie jest nieskończona ( kill, ctrl-alt-del, unplug ...). Dlaczego więc zawracać sobie głowę terminologią?
mouviciel,
5
„Jaki jest termin?” - „Jest to powszechnie nazywane pętlą nieskończoną”. Oto twoja odpowiedź. Wyraźnie nie jesteś zadowolony z tego terminu, ale to nie odbiera faktu, że (naturalne) języki są opisowe. „Pojęcie X” oznacza to, czego ludzie używają, a nie to, co powinni używać.
MSalters
5
To pytanie wydaje się być nie na temat, ponieważ jest to pytanie „nazwać to coś”. „Nazwij to” są złymi pytaniami z tych samych powodów, dla których „zidentyfikuj ten niejasny program telewizyjny, film lub książkę według jego postaci lub historii” to złe pytania: nie możesz ich Google, nie są w żaden sposób praktyczne, nie pomagaj nikomu innemu, a pozwalanie im otwiera drzwi do zadawania innych rodzajów marginalnych pytań. Zobacz blog.stackoverflow.com/2012/02/lets-play-the-guessing-game
gnat

Odpowiedzi:

24

Studiując CS, ten profesor nauczył nas, że istnieją pętle sprawdzania wstępnego ( while(cond) {}), sprawdzania końcowego ( do {} while(cond);) i sprawdzania środkowego . (Mogłem źle przetłumaczyć to na angielski, ale masz pomysł.)

C i C ++ nie mają tego drugiego (ISTR Ada ma to, BICBW), więc twoja konstrukcja jest do tego używana w C i C ++.

sbi
źródło
1
Tak, Ada ma to:loop ... exit when condition; ... end loop;
Keith Thompson,
@Keith: Dziękujemy za potwierdzenie! Minęło prawie 20 lat, odkąd stworzyłem trochę Ady.
sbi,
1
Za to, co jest warte, jestem profesjonalnym programistą od ponad 20 lat (i hobbystą dłużej) i nigdy nie słyszałem o tych terminach.
offby1
Jeśli chodzi o tłumaczenie - myślę, że „in” jest zwykle bardziej odpowiednie, gdy używa się „pre” i „post”, np. „Preorder / postorder / inorder tree traversal”.
Oak
1
Termin, w którym dorastałem, brzmiał: „pętla środkowego wyjścia”. Pracowałem w kilku różnych językach z wyraźną obsługą pętli mid-exit.
mjfgates,
13

Pierwszy kurs CS w Stanford ( Metodologia programowania Mehrana Sahamiego ) określa to jako półtorej pętli . I niekoniecznie jest to zła praktyka programowania. Rozważ ten przykład dotyczący zbierania danych wejściowych od użytkownika (zaczerpnięty z The Art and Science of Java autorstwa Erica Robertsa , gdzie Roberts nazywa to również pętlą półtora ):

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

A potem to samo rozwiązano za pomocą pętli i pół pomysłu, aby uniknąć powielania kodu:

while (true) {
    prompt user and read in a value
    if (value == sentinel) break;
    process the data value
}
ernes7a
źródło
10

Bez oficjalnej nazwy nazwałbym ją Broken Broken Loop . Niejednoznaczność tego terminu jest zamierzona, ponieważ przerwa w środku pętli jest nieco nieczysta, prawie jak goto.

użytkownik 281377
źródło
Powiedziałbym, znacznie gorzej niż goto. Wolałbym raczej zobaczyć goto niż fałszywie skonstruowany stan w takiej pętli.
Brian Knoblauch,
14
@Brian Co? Warunek „prawdziwy” sprawia, że ​​jest to oczywiste, a takie pętle są naprawdę powszechne. Na przykład, jeśli chcesz dodać każdy wiersz pliku do listy, musisz spróbować odczytać wiersz (zrób coś), przestań, jeśli się nie powiedzie (jeśli warunek się zepsuje), w przeciwnym razie dodaj go do listy i powtórz (zrób coś jeszcze).
Craig Gidney
7
Nie ma nic złego w przerwie w środku pętli. Jeśli musisz wykonać jakąś operację na każdym początku cyklu, będziesz musiał albo zduplikować kod, albo włożyć te operacje w warunek. Każdy wariant ma oczywiście wady. gotomiał również ważne aplikacje, np. emulację try ... wreszcie blok w C.
Malcolm
1
Malcolm: Możliwym problemem jest to, że podczas odczytu kodu trudniej jest zobaczyć, kiedy i dlaczego pętla została zamknięta. Dodatkowe problemy pojawiają się, gdy zagnieżdżasz dwie lub więcej takich pętli i chcesz wyrwać się z zewnętrznej pętli w oparciu o warunki występujące w wewnętrznej pętli.
user281377,
Powiedzmy, że masz pętli zdarzenia jazdy aplikację Xorg, jak (w pseudo-kodzie :) while(XEventGet(&ev) != NULL){ ... }, jesteś naturalnie będzie chciał sprawdzić klucze wewnątrz pętli: if(ev.key == XK_q) break;. Wykonanie następujących czynności while(XEventGet(&ev) != NULL && ev.key != XK_q){ ... }:, jest brzydkie i prawdopodobnie trudniejsze do odczytania niż przerwa w środkowej pętli. Co więcej, jeśli najpierw trzeba coś zrobić z wartością, zanim będzie można to sprawdzić? Naprawdę nie zamierzasz wpychać tego wszystkiego do podstawowej obudowy pętli, prawda?
Braden Best
8

Nie ma ostatecznej nazwy. Pętla nieskończona jest, moim zdaniem, właściwym terminem. Żadne pętle nie są naprawdę nieskończone, ale może to być potencjalnie nieskończone, ponieważ możliwe jest, że gałąź zawierająca przerwę nigdy nie nastąpi.

Jeśli powiesz komuś „utwórz nieskończoną pętlę i użyj przerwy dla warunku X”, a on będzie wiedział, co masz na myśli. Jeśli ktoś przegląda Twój kod i nie mówi nic więcej niż „Nie podoba mi się nieskończona pętla, którą napisałeś”, będziesz wiedział, o czym mówi (chyba że masz więcej niż jeden).

Bryan Oakley
źródło
1
To nie jest nieskończona pętla; ma dobrze zdefiniowany warunek zakończenia, podobnie jak normalna whilepętla, a sposób wykonania dowodu zakończenia jest dokładnie taki sam (znalezienie monotonicznie zmniejszającej się wartości to świetny początek).
Donal Fellows,
8

Jest to pętla „do-while” z funkcją warunkową w niewłaściwym miejscu.

Malfist
źródło
2
Tak, należy napisać: while (keep_going) {doSomething (); if (warunek) {keep_going = false; } else {doSomethingElse (); }}
Stephen Gross
10
więc ... mówisz, że jeśli prowadzisz kurs komputerowy i chcesz to opisać, powiedziałbyś „a teraz dowiemy się o * pętli do-while z warunkami w niewłaściwym miejscu „? To brzmi bardziej jak opinia religijna niż imię.
Bryan Oakley,
5
@StephenGross Ten fragment kodu jest okropną sugestią. Refaktoryzuj, aby umieścić rzeczywisty warunek w definicji pętli, lub po prostu użyj breaklub continue. Unikaj wartości wartowników za wszelką cenę, są one po prostu kolejnym przypadkowym stanem, który należy mentalnie śledzić, co ukrywa cel kodu.
Izkata,
2
Wartości sentymentalne to opóźnione gotos.
Winston Ewert,
2
-1 za bycie weenie z jednym wyjściem.
Donal Fellows,
6

Głosowałbym na „bezwarunkową pętlę” , podobną do „bezwarunkowego skoku”. Pokazuje dokładnie, co się dzieje (kod bezwarunkowo zapętla się), bez kłamstwa (w przeciwieństwie do „nieskończonej pętli”).

tdammers
źródło
1
Ale ma warunek zakończenia; to if/ breakw środku jest częścią wzoru.
Donal Fellows,
5

Jaki jest termin na taką pętlę - w której znajduje się instrukcja kontroli pętli „na zawsze” i „przerwa”?

To nieskończona pętla z warunkiem pęknięcia.

Zgodziłbym się z Ammilindem, że jeśli chcesz nadać mu specjalną nazwę, możesz nazwać to Infinite Partial Loop

Ramhound
źródło
1
To wcale nie jest nieskończone; punkt, w którym sprawdzany jest warunek zakończenia, znajduje się w innym miejscu.
Donal Fellows,
5

W Kodzie Rosetty ten szczególny wzór jest opisany jako pętla „N plus połowa” . Chociaż nie jest to mój ulubiony termin, nie jest straszny i jest wyraźnie wzorem, który jest użyteczny dla niektórych rodzajów pętli. (Alternatywą jest zduplikowanie kodu przed warunkiem - potencjalnie trudne w prawdziwych programach - lub zwiększenie głębokości zagnieżdżania kodu po warunku przy dodaniu zmiennej warunku pętli; ani nie poprawia możliwości utrzymania ani zrozumiałości kodu Jedynym powodem odrzucenia takich konstrukcji jest to, że ktoś nalega na napisanie pętli, aby być breakwolnym od pracy.)

Donal Fellows
źródło
4

Nie ma standardowego terminu, ale powiedziałbym, że jest to Częściowa pętla .

Ta pętla jest używana, gdy chcesz przerwać dopiero po ostatnim uruchomieniu części pętli (tzn. Częściowym wykonaniu). Jest używany, gdy nie znajdziesz odpowiedniej sytuacji, w której możesz chcieć przerwać całą pętlę .

W takim przypadku chcesz przerwać pętlę po co najmniej doSomething()ostatnim uruchomieniu.

iammilind
źródło
2

Muszę się tutaj zgodzić z sbi - podoba mi się termin pętli kontroli środkowej . Ten rodzaj konstrukcji był bardziej popularny, gdy programowanie strukturalne zaczęło się pojawiać i wiele języków miało dla nich obsługę składni.

To powiedziawszy, obecnie powszechnie wiadomo, że whilepętle są zwykle łatwiejsze do utrzymania, ponieważ łatwiej jest wnioskować o niezmiennikach i często lepiej radzą sobie z trudną pustą skrzynką.

W twoim szczególnym przypadku twoja pętla jest po prostu odpowiednikiem

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

więc chciałbym używać tylko breakwersji jeśli znakami doSomethinglub doSomethingElsezaangażowane liczne oświadczenia i wolę nie odłożyłem je do oddzielnych funkcji jak ty.

To powiedziawszy, jeśli twoja pętla jest bardziej skomplikowana niż iteracja (start, sprawdzenie, przyrost), powinieneś rozważyć przekształcenie jej w coś prostszego.

hugomg
źródło
1

Myślę, że jeśli spróbujemy znaleźć na to określenie, może:

Escapable Loop

LarsTech
źródło
-1. pytanie nie polega na wymyśleniu nazwy, chodzi o to, czy nazwa zwyczajowa już istnieje. Ponadto wszystkie pętle są „możliwe do przejścia”, więc nie jest to szczególnie skuteczna nazwa.
Bryan Oakley,
@BryanOakley Nieskończona pętla z definicji nie powinna być łamliwa. Prawdopodobnie nie powinno być na to terminu, oprócz złego programowania.
LarsTech
0

W każdym przypadku nie jest tak źle. Piszę tego rodzaju pętle za pomocą pewnego rodzaju interfejsów API. Powiedzmy na przykład, że masz obiekt pętli i musisz sprawdzić warunki w nim dość głęboko, na przykład:

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

Załóżmy teraz, że każda metoda getXXX może potencjalnie zwrócić wartość null. Wtedy nadal byłoby możliwe napisanie wyrażenia boolowskiego, chociaż dość skomplikowanego i nieczytelnego. A następnie musimy wykonać ponowną operację, aby uzyskać dostęp do bieżącego obiektu procedury obsługi. W takich przypadkach łatwiej mi napisać while (true)pętlę ze złamaniem i kontynuować.

Ingo
źródło