for (;;) {
//Something to be done repeatedly
}
Ich habe gesehen, dass so etwas oft benutzt wird, aber ich finde es ziemlich seltsam ... Wäre es nicht viel klarer zu sagen while(true)
oder etwas in dieser Richtung?
Ich vermute, dass dies (wie es der Grund für viele Programmierer ist, auf kryptischen Code zurückzugreifen) ein winziger Rand schneller ist?
Warum und ist es das wirklich wert? Wenn ja, warum nicht einfach so definieren:
#define while(true) for(;;)
Siehe auch: Was ist schneller: während (1) oder während (2)?
c++
c
optimization
readability
infinite-loop
Chris Cooper
quelle
quelle
TRUE
???TRUE
mit C zu tun? Das Standardmakro für das echte Boolen-Ergebnis in C99 ist immer nochtrue
. Woher kam dasTRUE
?#define EVER ;;
wurde aber in IOCCC verwendet .. :)#define while(TRUE)
Deklarieren eines Makros, das ein Argument enthält,TRUE
das nie verwendet wird, und verwandelt daher jede einzelne while-Schleife in Ihrem Programm in eine Endlosschleife?TRUE
stammt aus Header-Dateien, die der Windows-API zugeordnet sind. Es ist in keiner Weise mit VS 6.0 verwandt. Und wie gesagt, es hat weder mit C noch mit C ++ zu tun. In C ++ ist das "wahre" Literal nurtrue
(auch in VS 6.0), in C89 / 90 gibt es so etwas überhaupt nicht und in C99 ist es ein Makrotrue
. Dies gilt für alle C / C ++ - Compiler.Antworten:
quelle
ich bevorzuge
for(;;)
aus zwei Gründen.Zum einen erzeugen einige Compiler Warnungen
while(true)
(so etwas wie "Schleifenbedingung ist konstant"). Das Vermeiden von Warnungen ist immer eine gute Sache.Ein weiterer Grund ist, dass ich denke, dass dies
for(;;)
klarer und aussagekräftiger ist. Ich möchte eine Endlosschleife. Es buchstäblich hat keine Bedingung, es hängt von nichts. Ich möchte nur, dass es für immer weitergeht, bis ich etwas tue, um daraus auszubrechen.Während mit
while(true)
, na ja, was stimmt denn damit zu tun? Ich bin nicht daran interessiert, eine Schleife zu erstellen, bis wahr falsch wird, was in dieser Form wörtlich gesagt wird (Schleife, während wahr wahr ist). Ich möchte nur eine Schleife machen.Und nein, es gibt absolut keinen Leistungsunterschied.
quelle
for(;;)
, wird es offensichtlich seltsam aussehen. Aber ich würde empfehlen , versuchen, sich daran zu gewöhnen , weil es ist ein gemeinsames Idiom, und du gehst wieder hinein zu laufen. ;)for(;condition;)
. Dafür ist eine while-Schleife gedacht . Aber wie gesagt, mit einer Endlosschleife möchte ich nicht, dass der Compiler irgendeine Bedingung vergleicht . Naiv, mit einerwhile
Schleife, müsste estrue
jede Iteration testen (offensichtlich würde das nicht einmal der dümmste Compiler tun, aber es ist das Prinzip, das mich stört. Es scheint mir, als würde ich Ihren Code überbestimmen), während Sie mit einerfor(;;)
wörtlich sagen "Es gibt keine Bedingung zum Testen. Nur Schleife". Ich finde es das nächste Äquivalent zu Ihrerloop {...}
while(true)
eine Warnung ausgegeben wird.Persönlich benutze ich,
for (;;)
weil es keine Zahlen enthält, es ist nur ein Schlüsselwort. Ich ziehe es zuwhile (true)
,while (1)
,while (42)
,while (!0)
etc etc.quelle
true
ist nicht mehr eine magische Zahl alsfor
ein magisches Schlüsselwort oder dasfor(;;)
eine implizite magische Unendlichkeit verwendet. (while (42)
ist in der Tat ein Greuel.)for(;;)
wird sowieso schneller analysiert als die anderen#define LIFE 42
while (LIFE)
:)while(true)
enthält nicht zu einer beliebigen Anzahl. und für (;;) ist kein SchlüsselwortWegen Dennis Ritchie
Ich habe angefangen, es zu verwenden,
for (;;)
weil Dennis Ritchie es in K & R so macht, und wenn ich eine neue Sprache lerne, versuche ich immer, die klugen Jungs nachzuahmen.Dies ist idiomatisches C / C ++. Auf lange Sicht ist es wahrscheinlich besser, sich daran zu gewöhnen, wenn Sie vorhaben, viel im C / C ++ - Bereich zu tun.
Sie
#define
werden nicht funktionieren, da das Ding, das # define'd ist, wie eine C-Kennung aussehen muss.Alle modernen Compiler generieren denselben Code für die beiden Konstrukte.
quelle
while(TRUE)
, vermute ich, dass der Programmierer ein C-Neuling ist oder C aus einem For Dummies-Buch gelernt hat.In keinem vernünftigen Compiler ist es sicher schneller. Sie werden beide zu bedingungslosen Sprüngen zusammengestellt. Die for-Version ist einfacher zu tippen (wie Neil sagte) und wird klar, wenn Sie die Schleifensyntax verstehen.
Wenn Sie neugierig sind, gibt mir gcc 4.4.1 Folgendes für x86. Beide verwenden die x86- JMP- Anweisung.
kompiliert zu (teilweise):
quelle
for_infinite
ist schneller; 2 Zeichen weniger zuputs
.ich bevorzuge
for (;;)
weil es in verschiedenen C-ähnlichen Sprachen am konsistentesten ist.In C ++
while (true)
ist das in Ordnung, aber in C sind Sie auf einen Header angewiesen, um ihn zu definierentrue
, aber esTRUE
ist auch ein häufig verwendetes Makro. Wenn Sie es verwenden, istwhile (1)
es in C und C ++ und in JavaScript korrekt, jedoch nicht in Java oder C #, für die die Schleifenbedingung ein Boolescher Wert sein muss, z. B.while (true)
oderwhile (1 == 1)
. In PHP wird bei Schlüsselwörtern die Groß- und Kleinschreibung nicht berücksichtigt, aber die Sprache bevorzugt die GroßschreibungTRUE
.Allerdings
for (;;)
ist immer ganz korrekt in all diesen Sprachen.quelle
for (;;)
besser ist.while (1)
undfor (;;)
sind gebräuchliche Redewendungen für Endlosschleifen in C. Jeder, der ein C-Programm liest und Probleme beim Verstehen hat, wird wahrscheinlich Probleme mit dem Rest des Codes haben. Es lohnt sich nicht, C-Code zu schreiben, der von jemandem, der C nicht kennt, leicht gelesen werden kann.Ich persönlich bevorzuge die
for (;;)
Redewendung (die mit demselben Code kompiliert wird wiewhile (TRUE)
.Die Verwendung
while (TRUE)
ist in gewisser Hinsicht besser lesbar. Ich habe mich für die Verwendung derfor (;;)
Redewendung entschieden, weil sie auffällt .Ein Endlosschleifenkonstrukt sollte im Code leicht zu erkennen oder aufzurufen sein, und ich persönlich denke, der
for (;;)
Stil macht dies ein bisschen besser alswhile (TRUE)
oderwhile (1)
.Ich erinnere mich auch, dass einige Compiler Warnungen ausgeben, wenn der steuernde Ausdruck einer while-Schleife eine Konstante ist. Ich denke nicht, dass das zu viel passiert, aber nur das Potenzial für falsche Warnungen reicht aus, um dies zu vermeiden.
quelle
Ich habe gesehen, dass einige Leute es vorziehen, weil sie irgendwo ein #define haben:
Was ihnen erlaubt, dies zu schreiben:
quelle
FOREVER
definiertfor(;;)
, aber das ist nicht besser. IMO-Makros sollten nicht verwendet werden, um eine neue Sprache zu erfinden.#define BEGIN {
und#define END }
. Ich habe es sogar gesehen,#define DONKEYS_FLY (0)
damit sie sagen könnenif DONKEYS_FLY ...
. Wer sagt, dass Software langweilig ist?#define never while(0)
und#define always
Was ist mit (wenn Ihre Sprache dies unterstützt):
quelle
goto
die zahlreichen Nachteile, aber wenn der Algorithmus, den Sie implementieren möchten, aus einem Flussdiagramm stammt, ist dies die direkteste Übersetzung.goto
goto
ist, dass Sie sich keine Sorgenbreak
machen müssen, dass jemand ein hinzufügt , um Ihre Schleife weniger unendlich zu machen. (es sei denn, Sie befinden sich bereits in einer anderenwhile
oder einerfor
Schleife ...)Es gibt keinen Unterschied in Bezug auf den generierten Maschinencode.
Um dem Trend zu trotzen, würde ich jedoch argumentieren, dass die while (TRUE) -Form viel lesbarer und intuitiver ist als für (;;) und dass Lesbarkeit und Klarheit viel wichtigere Gründe für Codierungsrichtlinien sind als alle Gründe, die ich habe. Ich habe für den for (;;) - Ansatz gehört (ich ziehe es vor, meine Kodierungsrichtlinien auf soliden Argumenten und / oder dem Nachweis der Wirksamkeit selbst zu basieren).
quelle
for(;;)
ist der traditionelle Weg, dies in C und C ++ zu tun.while(true)
scheint die Konvention in C # und Java und anderen Sprachen zu sein. Ihr Kilometerstand kann variieren.Nicht nur ein bekanntes Muster, sondern eine Standardsprache in C (und C ++)
quelle
while (true)
aus dem gleichen Grund wie sieif (true)
.generiert mit Visual Studio eine Warnung (Bedingung ist konstant). Die meisten Orte, an denen ich gearbeitet habe, kompilieren Produktions-Builds mit Warnungen als Fehlern. So
Ist bevorzugt.
quelle
Beide sollten gleich sein, wenn Ihr Code vom Compiler optimiert wird. Um zu erklären, was ich unter Optimierung verstehe, finden Sie hier einen in MSVC 10 geschriebenen Beispielcode:
Wenn Sie es im Debug-Modus ( ohne Optimierung (/ Od) ) erstellen, zeigt die Demontage den deutlichen Unterschied. Es gibt zusätzliche Anweisungen für den
true
Zustand im Innerenwhile
.Wenn Sie Ihren Code jedoch im Release-Modus erstellen (mit der Standardgeschwindigkeit maximieren (/ O2) ), erhalten Sie für beide die gleiche Ausgabe. Beide Schleifen werden auf einen Sprungbefehl reduziert.
Was auch immer Sie verwenden, spielt für einen anständigen Compiler mit Geschwindigkeitsoptimierung keine Rolle.
quelle
Es ist eine Frage der persönlichen Präferenz, welcher Weg schneller ist. Persönlich bin ich ein Tipptypist und schaue während der Programmierung nie auf meine Tastatur - ich kann alle 104 Tasten auf meiner Tastatur tippen.
Ich finde, wenn schneller "while (TRUE)" einzugeben.
Ich fügte mental einige Fingerbewegungsmessungen hinzu und summierte sie. "for (;;)" hat ungefähr 12 Tastenbreiten der Bewegungen zurück und viertens (zwischen den Home-Tasten und den Tasten sowie zwischen den Home-Tasten und der UMSCHALTTASTE) "während (TRUE)" ungefähr 14 Tastenbreiten der Bewegungen zurück und hat vierte.
Ich bin jedoch weitaus weniger fehleranfällig, wenn ich letzteres schreibe. Ich denke mental in Worten zu einer Zeit, daher finde ich es schneller, Dinge wie "nIndex" einzugeben als Akronyme wie "nIdx", weil ich den Schriftzug tatsächlich mental buchstabieren muss, anstatt ihn in meinem Kopf zu sprechen und meine Finger automatisch sprechen zu lassen -Typ das Wort (wie Fahrrad fahren)
(Mein TypingTest.com-Benchmark = 136 WPM)
quelle
time head -10 >/dev/null
, geben Sie es jeweils 10 Mal ein und messen Sie die Ergebnisse. Ich wette, Sie sind schneller,for(;;)
wenn Sie nicht schummeln. Ich war um ungefähr 14%.Alle guten Antworten - Verhalten sollte genau gleich sein.
JEDOCH - Nehmen wir nur an, es hat einen Unterschied gemacht. Angenommen, einer von ihnen hat 3 weitere Anweisungen pro Iteration ausgeführt.
Sollte es dich interessieren?
NUR wenn das, was Sie in der Schleife tun, fast nichts ist , was fast nie der Fall ist der Fall ist.
Mein Punkt ist, es gibt Mikrooptimierung und Makrooptimierung. Mikrooptimierung ist wie "einen Haarschnitt bekommen, um Gewicht zu verlieren".
quelle
++i
überi++
?++i
undi++
kann möglicherweise erheblich sein, wenni
es sich um eine Instanz einer Klasse und nicht um eine integrierte handelt und der Compiler die triviale Optimierung nicht anwendet. Der Rat ist, sich eine Gewohnheit anzueignen, damit Sie nicht auffallen, wenn es darauf ankommt.++i
vsi++
ist, dass es Sie nichts kostet, die "Optimierung" vorzunehmen. Zwar macht es in den meisten Fällen absolut keinen Unterschied, aber sie sind ebenso einfach zu tippen. Warum also nicht standardmäßig die potenziell effizienteste bevorzugen? Und ich nehme an, dass dies auch hier gilt. Wenn man war ein kleines bisschen schneller als die anderen, warum nicht gehen für die ein schneller? Was würden wir dadurch verlieren? Beide sind ziemlich einfach zu lesen und auszutippen.Ich kann mir nicht vorstellen, dass ein lohnender Compiler einen anderen Code generieren würde. Selbst wenn dies der Fall wäre, gäbe es keine Möglichkeit zu bestimmen, ohne den jeweiligen Compiler zu testen, der effizienter war.
Ich schlage jedoch vor, Sie bevorzugen
for(;;)
aus folgenden Gründen:Eine Reihe von Compilern, die ich verwendet habe, generiert eine Warnung für konstante Ausdrücke für while (true) mit entsprechenden Einstellungen für die Warnstufe.
In Ihrem Beispiel ist das Makro TRUE möglicherweise nicht wie erwartet definiert
gibt es viele mögliche Varianten der unendlichen while - Schleife wie
while(1)
,while(true)
,while(1==1)
etc .; sofor(;;)
ist wahrscheinlich , in einem größeren Kohärenz führen.quelle
while(TRUE)
ausgewertetwhile(0)
wird, wird wahrscheinlich nicht davon profitierenfor(;;)
.while(true)
sollte auf jeden Fall bevorzugt werden. In C ++bool
ist reserviert und in C in C stdbool.h definiert (was es in C weniger sicher macht).for(;;)
beseitigt alle Zweifel.Ist klarer als:
Nicht, dass dies gilt, wenn Sie nicht verwenden
Sleep()
.quelle
timerService.scheduleRepeating (50, [] () { /* lots of code */ });
Die "für immer" -Schleife ist in eingebetteten Systemen als Hintergrundschleife beliebt. Einige Leute implementieren es als:
Und manchmal wird es implementiert als:
Und noch eine andere Implementierung ist:
Ein optimierender Compiler sollte für diese Fragmente denselben oder einen ähnlichen Assembler-Code generieren. Ein wichtiger Hinweis: Die Ausführungszeit für die Schleifen ist kein großes Problem, da diese Schleifen für immer andauern und mehr Zeit im Verarbeitungsabschnitt verbracht wird.
quelle
Ich nehme an, während (true) besser lesbar ist als für (;;) - es sieht so aus, als würde der Programmierer etwas in der for-Schleife verpassen :)
quelle
Der wichtigste Grund für die Verwendung von "for (;;)" ist die Angst, "while (TRUE)" zu verwenden, wenn Sie explorative Programmierung durchführen. Es ist einfacher, die Anzahl der Wiederholungen mit "for" zu steuern und die "for" -Schleife in eine Endlosschleife umzuwandeln.
Wenn Sie beispielsweise eine rekursive Funktion erstellen, können Sie die Anzahl der Aufrufe der Funktion begrenzen, bevor Sie sie in eine Endlosschleife konvertieren.
Wenn ich mir meiner Funktion sicher bin, konvertiere ich sie in eine Endlosschleife:
quelle