2008-10-22 8 views
8

Ein anderes Plakat fragte nach preferred syntax for infinite loops.Warum Endlosschleifen verwenden?

Eine weitere Frage: Warum verwenden Sie Endlosschleifen in Ihrem Code? Ich sehe typischerweise ein Konstrukt wie folgt aus:

for (;;) { 
    int scoped_variable = getSomeValue(); 
    if (scoped_variable == some_value) { 
    break; 
    } 
} 

Welche Sie in der Lage, lets get um den Wert von scoped_variable in der for oder while Klausel zu sehen. Was sind andere Anwendungen für "unendliche" Schleifen?

+0

In Verbindung stehende Frage: http://stackoverflow.com/questions/224138/infinite-loops-top-or-bottom – CesarB

Antwort

27

Eine Schleife wie:

while (true) 
{ 
    // do something 
    if (something else) break; 
    // do more 
} 

können Sie in der Mitte aus der Schleife zu brechen, anstatt zu Beginn (während/nach) oder Ende (do-while).

Wenn Sie eine komplexe Bedingung haben, möchten Sie vielleicht auch diesen Stil verwenden, um den Code klarer zu machen.

+2

FWIW, bevorzuge ich auch "while (wahr)" oder "while (1)" zu "for (;;)". Einfacher zu lesen, IMO. –

+0

Großartiges Beispiel eines Konstrukts, das andernfalls Duplizieren: A; while (etwas anderes) {B; A;} –

11

Ich benutze eine Endlosschleife für den Körper meines eingebetteten Steuercodes, da es entworfen ist, um für immer zu laufen, sobald es gestartet wird.

8

Endliche Automaten. Sie sollten nicht enden, bis Sie einen Endzustand erreicht haben, an welchem ​​Punkt Sie brechen oder zurückkehren.

+0

Ich verstehe dieses nicht. Warum schreibst du nicht einfach so etwas wie: "while (! Machine.state == finished) {machine.nextState();} –

+2

Es wäre nicht unbedingt so klar, besonders wenn du die Variable' machine.state' testen willst ein besonderer Punkt in der Schleife –

0

Ich benutzte sie, wenn ich auf mehrere Threads in C# warten wollte, aber jetzt benutze ich die ThreadPool-Klasse.

2

Ein Beispiel ist in einem Nachrichtenpumpentyp-Szenario, in dem Sie für immer die Verarbeitung von Nachrichten, die eintreffen, bis zum Stoppen der Schleife wiederholen möchten. Ein anderer ist, wenn Sie eine periodische Aktion ausführen möchten, dann könnten Sie eine Endlosschleife mit einem Schlaf darin schreiben (obwohl es besser sein könnte, irgendeine Form von Timer dafür zu verwenden).

Es kann einige andere Orte geben, an denen die Schleife eine bestimmte Menge an Arbeit ausführen muss, um zu bestimmen, ob sie beendet werden soll, und es könnte sauberer sein, nur break zu verwenden, wenn diese Bedingung erfüllt ist, anstatt einige externe Flags anzugeben Die Schleife sollte beendet werden. Im Allgemeinen obwohl ich denke, dass es besser ist, Ihre Ausgangsbedingung in die Schleifenanweisung zu setzen, wenn möglich, anstatt sie unendlich zu machen und die Schleife mit einer break Anweisung zu verlassen, weil die Ausgangsbedingung der Schleife offensichtlicher ist.

8
while(1) 
{ 
    game->update(); 
    game->render(); 
} 

Edit: Das heißt, meine app um eine Endlosschleife basiert grundlegend, und ich kann nicht einfach zu haben, um die ästhetische Reinheit immer endet durch Abfallen des Endes der Haupt-Refactoring alles gestört werden().

+1

Also, wie kommst du raus? –

+0

Ich mache eine Ladung cleanp und rufe dann 'exit()'. Ich brauchte diese clean shutdown Funktion sowieso (für zB . assert()), und warum zwei verschiedene Exit-Pfade haben? – Menkboy

4

Das ist ein unvollständiges Beispiel, weil es als Endtest-Schleife ohne Verlust von Klarheit, Funktion oder Leistung umgestaltet werden kann.

int scoped_variable; 
do { 
    scoped_variable = getSomeValue(); 
} while (scoped_variable != some_value); 

Endlosschleifen sind die meisten oft verwendet, wenn die Schleife Instanz nicht die Beendigung Test an der Oberseite oder der Unterseite, die im einfachsten Fall. Dies tritt auf, wenn die Schleife aus zwei Teilen besteht: Code, der jedes Mal ausgeführt werden muss, und Code, der nur zwischen jeder Iteration ausgeführt werden muss. Dies geschieht in Sprachen wie C, wenn man beispielsweise aus einer Datei liest oder ein Datenbankresultset verarbeitet, bei dem viel explizit gemacht werden muss. Die meisten Sprachen mit neueren Paradigmen können solchen Code tatsächlich in den Test integrieren.

+0

Sind Sie sicher, dass die Variable immer noch außerhalb des Blocks liegt? –

+0

Und warum nicht: for (int scoped_variable; (bereichsvariable = getSomeValue())! = some_value;) ; (leerer Schleifenkörper). Das funktioniert sowohl als C99 als auch als C++ Programm mit GCC/G ++ 4.3.1 unter Solaris. –

+0

Das Codefragment wurde bearbeitet, um ein Problem mit dem Umfang zu beheben. Das für (...) Loop ist auch legitim, ist aber ein etwas ungewöhnlicher Einsatz von (...) und viele Programmierer würden sich aus diesem Grund davor zurückhalten. – staticsan

0

Anders als eingebettete Systeme Situationen Endlosschleifen sind immer wirklich:

Repeat 
    Something 
Until Exit_Condition; 

Aber manchmal Exit_Condition ist nicht etwas, das tatsächlich am Ende der Schleife ausgewertet werden kann. Man könnte immer ein Flag setzen, dieses Flag verwenden, um den Rest der Schleife zu überspringen und dann am Ende testen, aber das bedeutet, dass man es mindestens zweimal testet (der Code ist etwas langsamer) und persönlich finde ich es weniger klar.

Es gibt Zeiten, in denen Klarheit im Handel für Geschwindigkeit Sinn macht, aber etwas, das weder Klarheit noch Geschwindigkeit gibt, nur um technisch korrekt zu sein? Klingt für mich eine schlechte Idee. Jeder kompetente Programmierer weiß, dass while (true) bedeutet, dass die Abbruchbedingung irgendwo innerhalb der Schleife liegt.

1

Es gibt andere Fragen, die sich darauf beziehen, ob/wann es in Ordnung ist, break in einer Schleife zu verwenden. Nehmen wir an, wir stimmen zu, dass es manchmal in Ordnung ist. Unter diesen Umständen (hoffentlich selten) würde ich eine Endlosschleife verwenden, wenn es eine Anzahl von Beendigungsbedingungen und keine identifizierbare "primäre" Beendigungsbedingung gibt.

Es vermeidet eine lange Reihe von Disjunktionen (oder ist) und lenkt die Aufmerksamkeit des Lesers auf die Tatsache, dass es (fast sicher) Brüche in der Schleife geben kann.

Letztendlich ist es eine Frage des Geschmacks.

1

Ich benutze sie, um Linux Daemons/Dienste zu schreiben, die Schleife, bis Kill/andere Termination Signale empfangen werden.

1

Infinite Loops sind vor allem in Daemon/Service-Prozessen oder der Hauptschleife in einem Spiel nützlich. Sie können sogar niedlich bekommen mit ihnen, zum Beispiel:

const bool heatDeathOfTheUniverse = false; 
do 
{ 
    // stuff 
} while(!heatDeathOfTheUniverse); 

Sie sollten nicht verwendet werden Threads zu „warten“ für Dinge wie, wie Fry vorgeschlagen wurde. Sie können dafür die Join-Methode eines Thread-Objekts verwenden.

Wenn Sie jedoch in einer Situation, wo Sie Ihre Tech-Führung sagt: „Endlosschleifen VERBOTEN sind & so sind mehrere Verfahren/Funktion gibt & breaks“ Sie können auch Dinge zu tun wie folgt aus:

bool done = false; 
while(!done) 
{ 
    if(done = AreWeDone()) continue; // continue jumps back to start of the loop 
} 

Natürlich, wenn du Tech Lead zwingt, solche Dinge zu tun, solltest du dich auf die Suche nach einem neuen Job machen.

Weitere Informationen zum Schlüsselwort continue finden Sie unter this MSDN Artikel.

3

Fast alle Apps verwenden einen unendlichHauptschleife. ;)

1

Webserver eine unendliche while-Schleife verwenden:

while(true) 
{ 
    //Do something like respond to requests 
} 

Sie müssen nicht am Ende, wenn Sie Ihre Web-Server-Anwendung schließen.

3

Ich würde eine unendliche Schleife verwenden, um das Lenksystem einer Rakete zu programmieren.

while (true) { go2Target () ; } 

Aus der Perspektive des Lenksystems der Lenkwaffe wird die einmal gestartete Schleife bis zum Ende der Zeit wiederholt.

Vielleicht ein Puristen würde bevorzugen

while (! blown2Bits ()) { go2Target () ; } 

aber dann, wie Sie die blow2Bits Methode implementieren Sie? was würde es bedeuten, wenn blow2Bits wahr werden würde?