Was ist der Begriff für "while (true)" - Schleife mit "break" im Inneren? [geschlossen]

24

Angenommen, ich habe eine Schleife in C ++ oder C #, die so aussieht:

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

Dies wird allgemein als "Endlosschleife" bezeichnet. Technisch gesehen ist es jedoch nicht unendlich - es wird aufhören, sobald die Kontrolle durchfließt break.

Was ist der Begriff für eine solche Schleife - die "loop forever" -Schleifensteueranweisung und "break" enthält?

scharfer Zahn
quelle
22
Ich glaube nicht, dass es einen speziellen Begriff gibt.
ChrisF
2
Gibt es eine Garantie dafür, dass die Kontrolle jemals durch die Pause fließt? Was ist, wenn in diesem Beispiel condition()immer false zurückgegeben wird? Ich würde sagen, es ist eine Endlosschleife mit bedingten Pausen.
JohnL
1
Auch ohne a breakist die Schleife nicht unendlich ( kill, Strg-Alt-Entf, Stecker ziehen ...). Warum sollten Sie sich also mit Terminologiedetails beschäftigen?
mouviciel
5
"Wie lautet der Begriff?" - "Dies wird im Allgemeinen als Endlosschleife bezeichnet." Das ist genau dort Ihre Antwort. Sie sind natürlich nicht zufrieden mit dem Begriff, aber das ändert nichts an der Tatsache, dass (natürliche) Sprachen beschreibend sind. Der "Begriff für X" ist das, was die Leute benutzen, nicht das, was sie benutzen sollten.
MSalters
5
Diese Frage scheint nicht zum Thema zu gehören, da es sich um eine Frage handelt, bei der es sich um einen "Namen für das Ding" handelt. "Nennen Sie das Ding" sind schlechte Fragen aus den gleichen Gründen, die "diese obskure TV-Show, diesen Film oder dieses Buch anhand seiner Figuren oder seiner Geschichte identifizieren" sind schlechte Fragen: Sie können sie nicht googeln, sie sind in keiner Weise praktisch, sie Helfen Sie niemand anderem, und wenn Sie es zulassen, können Sie auch andere Arten von Randfragen stellen. Siehe blog.stackoverflow.com/2012/02/lets-play-the-guessing-game
Gnat

Antworten:

24

Dieser Professor hat CS studiert und uns beigebracht, dass es Pre-Checking-Schleifen ( while(cond) {}), Post-Checking-Schleifen ( do {} while(cond);) und Middle-Checking-Schleifen gibt . (Ich habe das vielleicht schlecht ins Englische übersetzt, aber Sie haben die Idee.)

C und C ++ haben das letztere nicht (ISTR Ada hat es, BICBW), also wird Ihr Konstrukt für das in C und C ++ verwendet.

sbi
quelle
1
Ja, Ada hat dies:loop ... exit when condition; ... end loop;
Keith Thompson
@ Keith: Danke für die Bestätigung! Es ist fast 20 Jahre her, dass ich Ada gemacht habe.
sbi
1
Für das, was es wert ist, bin ich seit über 20 Jahren ein professioneller Programmierer (und länger ein Hobbyist), und ich habe diese Begriffe noch nie gehört.
offby1
In Bezug auf die Übersetzung - Ich denke, "In" ist normalerweise passender, wenn "Pre" und "Post" verwendet werden, z. B. "Preorder / Postorder / Inorder Tree Traversal".
Oak
1
Der Begriff, mit dem ich aufgewachsen bin, war "Mid-Exit Loop". Ich habe in verschiedenen Sprachen gearbeitet und Mid-Exit-Schleifen ausdrücklich unterstützt.
mjfgates
13

Der allererste Kurs in CS bei Stanford ( Programming Methodology von Mehran Sahami ) bezeichnet dies als eineinhalb Schleife . Und es ist nicht unbedingt eine schlechte Programmierpraxis. Betrachten Sie das folgende Beispiel zum Sammeln von Benutzereingaben (entnommen aus " The Art and Science of Java" von Eric Roberts , wo Roberts es auch als eineinhalb Schleife bezeichnet ):

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

Und dann das Gleiche, das mit der eineinhalb- minütigen Schleife gelöst wurde , um doppelten Code zu vermeiden:

while (true) {
    prompt user and read in a value
    if (value == sentinel) break;
    process the data value
}
ernes7a
quelle
10

Ohne offiziellen Namen würde ich es Broken Loop nennen . Die Mehrdeutigkeit dieses Begriffs ist beabsichtigt, da eine Unterbrechung in der Mitte einer Schleife ein bisschen unrein ist, fast wie eine goto.

user281377
quelle
Ich würde sagen, viel schlimmer als ein Goto. Ich würde viel lieber ein goto als einen falsch konstruierten Zustand in einer solchen Schleife sehen.
Brian Knoblauch
14
@ Brian Was? Die "wahre" Bedingung macht es offensichtlich und Schleifen wie diese sind wirklich üblich. Wenn Sie beispielsweise jede Zeile einer Datei in eine Liste aufnehmen möchten, müssen Sie versuchen, die Zeile zu lesen (etwas zu tun), anzuhalten, wenn dies fehlgeschlagen ist (wenn die Bedingung nicht erfüllt ist), oder sie der Liste hinzufügen und wiederholen (etwas tun) sonst).
Craig Gidney
7
Es ist nichts falsch daran, mitten in einer Schleife zu brechen. Wenn Sie bei jedem Start des Zyklus eine Operation ausführen müssen, müssen Sie entweder den Code duplizieren oder diese Operationen in die Bedingung einfügen. Jede Variante hat eindeutig Nachteile. gotoauch hatte gültige Anwendungen, zB Emulation eines try ... schließlich in C. blockieren
Malcolm
1
Malcolm: Das mögliche Problem ist, dass es beim Lesen des Codes schwieriger ist zu erkennen, wann und warum die Schleife beendet wird. Zusätzliche Probleme treten auf, wenn Sie zwei oder mehr solcher Schleifen verschachteln und die äußere Schleife aufgrund einer in der inneren Schleife festgestellten Bedingung verlassen möchten.
user281377
Angenommen , Sie haben eine Ereignisschleife haben eine Xorg Anwendung der Fahrt, wie (in Pseudo-Code :) while(XEventGet(&ev) != NULL){ ... }, sind Sie natürlich die Schlüssel in der Schleife überprüfen , gehen zu wollen: if(ev.key == XK_q) break;. Folgendes tun while(XEventGet(&ev) != NULL && ev.key != XK_q){ ... }:, ist hässlich und wahrscheinlich schwerer zu lesen als eine Pause in der Mitte der Schleife. Und was ist, wenn etwas zuerst auf den Wert eingestellt werden muss, bevor es überprüft werden kann? Du wirst das alles nicht ernsthaft in den Basisfall der Schleife stecken, oder?
Braden Best
8

Es gibt keinen endgültigen Namen. Endlosschleife ist, denke ich, der passende Begriff. Keine Schleife ist wirklich unendlich, aber dies hat das Potenzial, effektiv unendlich zu sein, da es möglich ist, dass der Zweig, der die Unterbrechung enthält, niemals auftritt.

Wenn Sie jemandem sagen, "erstelle eine Endlosschleife und verwende eine Unterbrechung für Bedingung X", wird er wissen, was Sie meinen. Wenn jemand Ihren Code überprüft und nichts weiter sagt als "Ich mag die Endlosschleife, die Sie geschrieben haben, nicht", wissen Sie, wovon er spricht (es sei denn, Sie haben natürlich mehr als eine).

Bryan Oakley
quelle
1
Es ist keine Endlosschleife; Es hat eine genau definierte Abbruchbedingung, genau wie eine normale whileSchleife, und die Art und Weise, wie Sie den Abbruchnachweis erbringen, ist genau dieselbe (eine monoton abnehmende Metrik zu finden, ist ein guter Anfang).
Donal Fellows
8

Es ist eine Do-While-Schleife mit der Bedingung an der falschen Stelle.

Malfist
quelle
2
Ja, es sollte geschrieben werden: while (keep_going) {doSomething (); if (Bedingung) {keep_going = false; } else {doSomethingElse (); }}
Stephen Gross
10
Sie sagen also, wenn Sie einen Computerkurs unterrichten und dies beschreiben möchten, würden Sie sagen: "Und jetzt werden wir etwas über die * do-while-Schleife mit der Bedingung an der falschen Stelle lernen "? Das klingt eher nach einer religiösen Meinung als nach einem Namen.
Bryan Oakley
5
@StephenGross Dieser Codeausschnitt ist ein schrecklicher Vorschlag. Refactor, um die aktuelle Bedingung in die Schleifendefinition einzufügen, oder verwenden Sie einfach breakoder continue. Vermeiden Sie Sentinel-Werte um jeden Preis. Sie sind nur ein willkürlicher Zustand, den Sie im Kopf behalten müssen und der den Zweck des Codes verschleiert.
Izkata,
2
Sentinalwerte sind verzögerte gotos.
Winston Ewert
2
-1 für ein Single-Exit-Weenie.
Donal Fellows
6

Ich würde für "bedingungslose Schleife" stimmen , ähnlich wie "bedingungsloser Sprung". Es zeigt genau, was los ist (der Code schleift bedingungslos), ohne zu lügen (im Gegensatz zu "Endlosschleife").

tdammers
quelle
1
Es gibt jedoch eine Kündigungsbedingung. Das if/ breakin der Mitte ist Teil des Musters.
Donal Fellows
5

Was ist der Begriff für eine solche Schleife - die "loop forever" -Schleifensteueranweisung und "break" enthält?

Es ist eine Endlosschleife mit einer Unterbrechungsbedingung.

Ich würde mit ammilind, dass zustimmen , wenn Sie es einen besonderen Namen geben wollte man es nennen könnte ein Infinite Partial - Loop

Ramhound
quelle
1
Es ist überhaupt nicht unendlich; Der Punkt, an dem die Kündigungsbedingung überprüft wird, befindet sich nur an einer anderen Stelle.
Donal Fellows
5

In Rosetta Code wird dieses spezielle Muster als "N plus eine halbe" Schleife beschrieben . Obwohl es nicht mein Lieblingsbegriff ist, ist es nicht schrecklich und ist eindeutig ein Muster, das für einige Arten von Schleifen nützlich ist. (Die Alternativen sind das Duplizieren des Vor-der-Bedingung-Codes - möglicherweise schwierig in realen Programmen - oder das Erhöhen der Verschachtelungstiefe des Nach-der-Bedingung-Codes, während eine Schleifenbedingungsvariable hinzugefügt wird; weder die Wartbarkeit noch die Verständlichkeit des Codes werden verbessert Der einzige Grund, solche Konstrukte abzulehnen, ist, wenn man darauf besteht, Schleifen zu schreiben, um frei zu sein break.)

Donal Fellows
quelle
4

Es gibt keinen Standardbegriff, aber ich würde es als Teilschleife bezeichnen .

Diese Schleife wird verwendet, wenn Sie nur einen Teil der Schleife ein letztes Mal ausführen möchten (dh eine teilweise Ausführung). Es wird verwendet, wenn Sie keine geeignete Situation finden, in der Sie die gesamte Schleife unterbrechen möchten .

In diesem Fall möchten Sie die Schleife unterbrechen, nachdem Sie sie mindestens doSomething()ein letztes Mal ausgeführt haben.

iammilind
quelle
2

Ich muss mich hier mit sbi einverstanden erklären - ich mag den Begriff des mittleren Prüfkreises . Diese Art von Konstrukt war populärer, als Structured Programming begann, und viele Sprachen hatten syntaktische Unterstützung für sie.

Das heißt, es ist mittlerweile weit verbreitet, dass whileSchleifen in der Regel besser zu handhaben sind, da es einfacher ist, über Invarianten nachzudenken, und sie den schwierigen leeren Fall häufig besser handhaben.

In Ihrem speziellen Fall ist Ihre Schleife nur äquivalent zu

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

Daher würde ich die breakVersion nur verwenden, wenn eine doSomethingoder doSomethingElsemehrere Anweisungen vorhanden sind, und sie lieber nicht wie Sie in separate Funktionen einteilen.

Das heißt, wenn Ihre Schleife komplizierter ist als eine Iteration (Starten, Prüfen, Inkrementieren), sollten Sie überlegen, sie in etwas Einfacheres umzugestalten.

hugomg
quelle
1

Ich denke, wenn wir versuchen werden, einen Begriff dafür zu finden, vielleicht:

Escapable-Schleife

LarsTech
quelle
-1. Bei der Frage geht es nicht darum, einen Namen zu erfinden, sondern darum, ob bereits ein gebräuchlicher Name existiert. Außerdem sind alle Schleifen "escapable", so dass es sich nicht um einen besonders effektiven Namen handelt.
Bryan Oakley
@BryanOakley Eine Endlosschleife sollte per Definition nicht zerbrechlich sein. Es sollte wahrscheinlich keinen anderen Begriff dafür geben als schlechte Programmierung.
LarsTech
0

Es ist nicht in jedem Fall so schlimm. Ich finde mich dabei, diese Art von Schleifen mit bestimmten Arten von APIs zu schreiben. Nehmen wir zum Beispiel an, Sie haben ein Schleifenobjekt und müssen nach Bedingungen suchen, die ziemlich tief in diesem Objekt liegen, wie zum Beispiel:

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

Angenommen, jede getXXX-Methode könnte möglicherweise null zurückgeben. Dann wäre es immer noch möglich, einen booleschen Ausdruck zu schreiben, obwohl dieser ziemlich kompliziert und unleserlich ist. Und dann müssen wir fast das gleiche wiederholen, um das aktuelle Handler-Objekt zu erhalten. In solchen Fällen fällt es mir leichter, eine while (true)Schleife mit break zu schreiben und fortzufahren.

Ingo
quelle