Ist "für (;;)" schneller als "während (WAHR)"? Wenn nicht, warum benutzen die Leute es?

164
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)?

Chris Cooper
quelle
51
Was ist TRUE???
AnT
20
@Steven Sudit: Was hat TRUEmit C zu tun? Das Standardmakro für das echte Boolen-Ergebnis in C99 ist immer noch true. Woher kam das TRUE?
Am
31
Das Makro funktioniert nicht, #define EVER ;;wurde aber in IOCCC verwendet .. :)
18
Ist das nicht ein Makro zum #define while(TRUE)Deklarieren eines Makros, das ein Argument enthält, TRUEdas nie verwendet wird, und verwandelt daher jede einzelne while-Schleife in Ihrem Programm in eine Endlosschleife?
AshleysBrain
9
@Steven Sudit: Nein. Es gibt kein "Standardmakro in VS 6.0". Das Makro TRUEstammt 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 nur true(auch in VS 6.0), in C89 / 90 gibt es so etwas überhaupt nicht und in C99 ist es ein Makro true. Dies gilt für alle C / C ++ - Compiler.
Am

Antworten:

262
  1. Es ist nicht schneller.
  2. Wenn Sie sich wirklich interessieren, kompilieren Sie mit der Assembler-Ausgabe für Ihre Plattform und sehen Sie nach.
  3. Es spielt keine Rolle. Das ist nie wichtig. Schreiben Sie Ihre Endlosschleifen, wie Sie möchten.
Ben Zotto
quelle
227
Intuitiv bietet die Optimierung einer Endlosschleife das Potenzial für eine unendliche Beschleunigung. Gut, dass wir dann nicht auf Intuition programmieren. :-)
Steven Sudit
5
Ich nehme an, du hast recht. Ich glaube, ich war in "religiöse" Debatten über Kleinigkeiten verwickelt. Danke, dass du mein Gewissen erschüttert hast. : D
Chris Cooper
6
@Steven LOL, das ist interessant, aber dann denken Sie daran, dass das einzige Szenario, in dem Sie tatsächlich das Potenzial einer unendlichen Beschleunigung erreicht haben, darin besteht, dass die Schleife niemals bricht und wirklich unendlich läuft, was wahrscheinlich entweder ein Fehler ist oder, falls beabsichtigt, der Fall sein wird eine unendliche Wartezeit, bis es dieses Potenzial erreicht.
AaronLS
7
@ Chris. In der Programmierung wie im Leben sind religiöse Debatten Ihre Zeit nur für Dinge wert, die wirklich wichtig sind. Dies ist einfach nicht eines dieser Dinge. Wie Sie sehen können, hat jeder eine einfache Art, eine Endlosschleife zu schreiben. Wählen Sie selbst aus, was Sie für die kleinen Dinge am glücklichsten macht, und führen Sie dann Ihren Profiler mit dem Code aus, der wichtig ist. :)
Ben Zotto
3
Es war wichtig, da einige frühe Compiler auf einigen Plattformen eine Konstante geladen und einen bedingten Sprung daraus gemacht haben. Was an jenen Tagen Hardware bedeutete.
Peterchen
176

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.

jalf
quelle
73
+1 zur Vermeidung von Warnungen. Aber was die Klarheit betrifft, finde ich zwar klarer als in diesem Zusammenhang. Ich denke, dieser Aspekt hängt nur von den persönlichen Vorlieben ab.
Tim
14
Ja, Vorliebe und Gewohnheit. Wenn Sie nicht daran gewöhnt sind zu sehen 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. ;)
Jalf
7
Jalfs Kommentar, dass es idiomatisch ist, ist hier wirklich die Antwort. Es ist allgemein für „Endlosschleife“ einfach verwendet , weil es ist die allgemein verwendete Art und Weise des Schreibens „Endlosschleife“ in C hat es nicht einen guten Grund für ein Idiom zu sein - es ist nur ein sich selbst verstärkender Konvention.
Café
7
@Steve: Ich verstehe nicht, warum ich jemals verwenden würde 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 einer whileSchleife, müsste es truejede 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 einer for(;;)wörtlich sagen "Es gibt keine Bedingung zum Testen. Nur Schleife". Ich finde es das nächste Äquivalent zu Ihrer loop {...}
Vorstellung
32
Ihr Compiler ist zum Kotzen, wenn while(true)eine Warnung ausgegeben wird.
Albert
56

Persönlich benutze ich, for (;;)weil es keine Zahlen enthält, es ist nur ein Schlüsselwort. Ich ziehe es zu while (true), while (1), while (42), while (!0)etc etc.

ta.speot.is
quelle
38
0, 1 und unendlich sind akzeptable magische Zahlen. Die Erweiterung von 0 und 1 auf falsch und wahr ist kein Verlust. trueist nicht mehr eine magische Zahl als forein magisches Schlüsselwort oder das for(;;)eine implizite magische Unendlichkeit verwendet. ( while (42)ist in der Tat ein Greuel.)
38
Tangente: Einer meiner CS-Professoren sagte: "Es gibt nur drei Zahlen in der Programmierung: 0, 1 und n. Alles andere wird als magische Zahl bezeichnet."
Ben Zotto
21
während (42) am coolsten ist, kein anderes Ergebnis in Bezug auf while (1) oder while (wahr) oder while (! 0) liefert und eine philosophische Bedeutung hat. Ich nehme an, es for(;;)wird sowieso schneller analysiert als die anderen
ShinTakezou
2
@ShinTakezou viel besser zu #define LIFE 42 while (LIFE):)
mr5
1
gut while(true)enthält nicht zu einer beliebigen Anzahl. und für (;;) ist kein Schlüsselwort
RiaD
49

Wegen 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 #definewerden 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.

Mark Harrison
quelle
10
Ja, so wissen Sie, dass jemand C von K & R gelernt hat, so wie es gelernt werden sollte. Immer wenn ich sehe while(TRUE), vermute ich, dass der Programmierer ein C-Neuling ist oder C aus einem For Dummies-Buch gelernt hat.
Kristopher Johnson
13
Ich höre, dass diese Neulinge auch einen neuen Funktionsdefinitionsstil verwenden .
Justin
46

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.

void while_infinite()
{
    while(1)
    {
    puts("while");
    }
}

void for_infinite()
{
    for(;;)
    {
    puts("for");
    }
}

kompiliert zu (teilweise):

.LC0:
.string "while"
.text
.globl while_infinite
    .type   while_infinite, @function
while_infinite:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
.L2:
    movl    $.LC0, (%esp)
    call    puts
    jmp .L2
    .size   while_infinite, .-while_infinite
    .section    .rodata
.LC1:
    .string "for"
    .text
.globl for_infinite
    .type   for_infinite, @function
for_infinite:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $24, %esp
.L5:
    movl    $.LC1, (%esp)
    call    puts
    jmp .L5
    .size   for_infinite, .-for_infinite
Matthew Flaschen
quelle
Ich bezweifle, dass es sogar im Debug-Modus schneller ist.
Steven Sudit
106
for_infiniteist schneller; 2 Zeichen weniger zu puts.
Dave Jarvis
43

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 definieren true, aber es TRUEist auch ein häufig verwendetes Makro. Wenn Sie es verwenden, ist while (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)oder while (1 == 1). In PHP wird bei Schlüsselwörtern die Groß- und Kleinschreibung nicht berücksichtigt, aber die Sprache bevorzugt die Großschreibung TRUE.

Allerdings for (;;)ist immer ganz korrekt in all diesen Sprachen.

Boann
quelle
9
Danke für deine Antwort! Ich denke, dies ist tatsächlich die erste Antwort, die einen objektiven Weg zeigt , der for (;;)besser ist.
Chris Cooper
8
Ich glaube nicht, dass ich jemals Code schreiben muss, der in C, C ++, JavaScript, Java und C # korrekt ist. Sie sind verschiedene Sprachen.
Keith Thompson
6
@KeithThompson Es geht nicht darum, Code zu schreiben, der in vielen Sprachen korrekt ist. Ich denke, es geht darum, Fehlinterpretationen zwischen Entwicklern mit unterschiedlichem Hintergrund zu vermeiden.
Mauro Sampietro
6
@sam: Beide while (1)und for (;;)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.
Keith Thompson
6
@KeithThompson Während ein kompetenter Leser von C auf jeden Fall mit beiden Redewendungen vertraut sein sollte, könnte dies auch nützlich sein, wenn der Autor ein polygloter Programmierer ist. Bei meinem letzten Job habe ich täglich in JS, ActionScript und PHP gearbeitet. Durch die Vereinheitlichung der Art und Weise, wie Code geschrieben wird (wo dies sinnvoll ist), kann die Programmierung beschleunigt und die Wartung vereinfacht werden.
Ionoclast Brigham
21

Ich persönlich bevorzuge die for (;;)Redewendung (die mit demselben Code kompiliert wird wie while (TRUE).

Die Verwendung while (TRUE)ist in gewisser Hinsicht besser lesbar. Ich habe mich für die Verwendung der for (;;)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 als while (TRUE)oder while (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.

Michael Burr
quelle
17

Ich habe gesehen, dass einige Leute es vorziehen, weil sie irgendwo ein #define haben:

#define EVER ;;

Was ihnen erlaubt, dies zu schreiben:

for (EVER)
{
    /* blah */
}
rmeador
quelle
24
Ich habe das auch gesehen; aber es ist kein guter Grund, es zu bevorzugen. Als Betreuer müssten Sie immer noch die Makrodefinition überprüfen, um sicherzugehen, dass sie das tut, was Sie erwarten, während der ursprüngliche Code klar genug war. In RTOS VxWorks ist ein Makro FOREVERdefiniert for(;;), aber das ist nicht besser. IMO-Makros sollten nicht verwendet werden, um eine neue Sprache zu erfinden.
Clifford
8
Tatsächlich besteht der Zweck von Makros in einigen Sprachen darin, eine neue Syntax zu erfinden. Aber unabhängig davon, ob 'für (EVER)' in C / C ++ abscheulich ist.
Dan Olson
15
Einige Leute machen lustige Dinge, wie wenn sie Pascal mögen, sagen sie #define BEGIN {und #define END }. Ich habe es sogar gesehen, #define DONKEYS_FLY (0)damit sie sagen können if DONKEYS_FLY .... Wer sagt, dass Software langweilig ist?
Mike Dunlavey
11
In Kalifornien glaube ich, dass Sie für (;;) LIKE_FOREVER
Martin Beckett
1
Ich konnte nicht widerstehen: #define never while(0)und#define always
alfC
16

Was ist mit (wenn Ihre Sprache dies unterstützt):

start:
/* BLAH */
goto start;
Pfusch
quelle
... die in den Händen eines vernünftigen Compilers eine identische Ausgabe erzeugen sollten.
Ben Zotto
9
+1! Es verbessert nicht gotodie zahlreichen Nachteile, aber wenn der Algorithmus, den Sie implementieren möchten, aus einem Flussdiagramm stammt, ist dies die direkteste Übersetzung.
Edmund
4
Ich persönlich halte eine utilitaristische Sichtweise über goto. Es gibt keine Raubvögel. Die Raubvögel sind Menschen. Und es waren Leute, die anfingen, mit goto Spaghetti-Code zu erstellen. Außerdem sieht die zusammengesetzte Ausgabe für eine Schleife ziemlich genau so aus. Die Befehlssätze für Computer haben keine Konzepte für "für" oder "während", sondern nur "springen".
Josaphatv
Niemals jemals benutzengoto
Edward Karak
Das wirklich Schöne daran gotoist, dass Sie sich keine Sorgen breakmachen müssen, dass jemand ein hinzufügt , um Ihre Schleife weniger unendlich zu machen. (es sei denn, Sie befinden sich bereits in einer anderen whileoder einer forSchleife ...)
12

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).

Jason Williams
quelle
6
Das hängt von Ihrer Sprache ab. 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.
Billy ONeal
9
Ja, und jemand, der mit C oder C ++ nicht sehr vertraut ist, findet STRING_SCAN_FORMATTED möglicherweise besser lesbar als sscanf, aber Sie sehen niemanden, der #define STRING_SCAN_FORMATTED sscanf an die Spitze seines Codes setzt.
ta.speot.is
4
Ich würde sagen , den idiomatischen Weg , es zu tun besser war die Lesbarkeit Ihrer Entwickler. Ansonsten braucht man wirklich bessere Entwickler.
Jalf
5
@despart: Wenn jemand nicht genug mit C ++ vertraut ist, um diese Redewendung als das zu erkennen, was sie ist, muss er sich verdammt noch mal von meiner Codebasis fernhalten.
Billy ONeal
4
Ich stimme zu, dass der idiomatische Weg am besten lesbar sein sollte. Deshalb müssen die Redewendungen immer in Frage gestellt und geändert werden, wenn sich Sprachen und Praktiken weiterentwickeln. Es dauerte Jahre, bis der schreckliche "idiomatische" Codierungsstil von K & R durch den modernen, besser lesbaren Stil ersetzt wurde, aber es passierte immer noch.
Jason Williams
11

Nicht nur ein bekanntes Muster, sondern eine Standardsprache in C (und C ++)

James McLeod
quelle
3
Ja, und ich denke, einige Compiler warnen while (true)aus dem gleichen Grund wie sie if (true).
Steven Sudit
11
while(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

for(;;)

Ist bevorzugt.

Michael
quelle
7
Welche Version von Visual Studio verwenden Sie? Mit 2008 bekomme ich diese Warnung nicht einmal auf Warnstufe 4.
Jörgen Sigvardsson
11

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:

int x = 0;

while(true) // for(;;)
{
    x +=1;

    printf("%d", x);
}

Wenn Sie es im Debug-Modus ( ohne Optimierung (/ Od) ) erstellen, zeigt die Demontage den deutlichen Unterschied. Es gibt zusätzliche Anweisungen für den trueZustand im Inneren while.

while(true)
00D313A5  mov         eax,1                //extra 
00D313AA  test        eax,eax              //extra
00D313AC  je          main+39h (0D313B9h)  //extra
    {
        x +=1;
00D313AE  mov         eax,dword ptr [x]  
00D313B1  add         eax,1  
00D313B4  mov         dword ptr [x],eax  
    printf("%d", x);
    ...
    }
00D313B7  jmp         main+25h (0D313A5h)  


for(;;)
    {
        x +=1;
00D213A5  mov         eax,dword ptr [x]  
00D213A8  add         eax,1  
00D213AB  mov         dword ptr [x],eax  
    printf("%d", x);
    ...
    }
00D213AE  jmp         main+25h (0D213A5h)  

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.

for(;;)
    {
        x +=1;
01291010  inc         esi  

        printf("%d", x);
    ...
    }
0129101C  jmp         main+10h (1291010h)  

    while(true)
    {
        x +=1;
00311010  inc         esi  

        printf("%d", x);
    ...
    }
0031101C  jmp         main+10h (311010h)  

Was auch immer Sie verwenden, spielt für einen anständigen Compiler mit Geschwindigkeitsoptimierung keine Rolle.

SylvanBlack
quelle
Das ist eigentlich ein sehr guter Punkt! Ohne Optimierung unterscheiden sich auch moderne Compiler durch mehrere Anweisungen.
9

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)

Mark Rejhon
quelle
3
Ich glaube, das OP bezog sich auf die Laufzeitgeschwindigkeit, nicht auf die Schreibgeschwindigkeit.
Ich weiß. Musste nur auch diese Basis abdecken.
Mark Rejhon
7
s / persönliche Präferenz / individuelle Gewohnheit /
SamB
@SamB: Kommentar zur Abstimmung für s ///. xD Und ja, obwohl ich vorgeschlagen habe, dass dies an der Laufzeitgeschwindigkeit liegen könnte, wusste ich die tatsächliche Antwort nicht. Wenn das so wäre, wäre ich glücklich gewesen.
Chris Cooper
Führen Sie es aus 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%.
PSkocik
6

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".

Mike Dunlavey
quelle
3
Wie oft sehen Sie Menschen bevorzugen gesagt ++iüber i++?
Dennis Zickefoose
7
@ Tennis Zickefoose: Der Unterschied zwischen ++iund i++kann möglicherweise erheblich sein, wenn ies 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.
Clifford
5
Die Sache mit ++ivs i++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.
Jalf
2
@ Tennis Zickefoose: Du hast recht. Ich sehe das sehr auf SO, und Cliffords Kommentar ist richtig. Darüber hinaus gibt es etwas, das ich bei SO nicht oft sehe, und so wird eine Makrooptimierung durchgeführt, z . B. eine 43-fache Beschleunigung: stackoverflow.com/questions/926266/… . Ich frage mich also über unsere Prioritäten.
Mike Dunlavey
2
@ Mike: Ja, aber das ist ein Vergleich zwischen Äpfeln und Orangen. Einen Haarschnitt zu bekommen kostet Zeit und wahrscheinlich sogar Geld. Ich bin damit einverstanden, dass es sich um eine solche Mikrooptimierung handelt, dass es nicht wirklich wichtig ist. Aber es kostet uns auch nichts. Wenn ich wählen kann, ob ich nach links oder rechts gehen möchte und die Entfernung gleich ist, das Gelände gleich ist, alles gleich ist, außer dass der linke Pfad einen geringfügigen mikroskopischen Vorteil hat, warum nicht nach links gehen? Du hast recht, es ist kein beeindruckendes Argument. Aber wenn die Kosten buchstäblich Null sind, sehe ich keinen Grund, die weniger optimale Route zu bevorzugen.
Jalf
5

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 .; so for(;;)ist wahrscheinlich , in einem größeren Kohärenz führen.

Clifford
quelle
TRUE ist möglicherweise nicht #define TRUE 1, aber jede Codebasis, in der while(TRUE)ausgewertet while(0)wird, wird wahrscheinlich nicht davon profitieren for(;;).
Justin
@Justin: Ich stimme zu, es wäre wirklich pervers und es ist nicht das stärkste der drei Argumente, aber Bjarne Stoustrup verwendet ein ähnliches Argument, um das NULL-Makro in C ++ zu vermeiden. while(true)sollte auf jeden Fall bevorzugt werden. In C ++ boolist reserviert und in C in C stdbool.h definiert (was es in C weniger sicher macht). for(;;)beseitigt alle Zweifel.
Clifford
5
for(;;Sleep(50))
{
    // Lots of code
}

Ist klarer als:

while(true)
{
    // Lots of code
    Sleep(50);
}

Nicht, dass dies gilt, wenn Sie nicht verwenden Sleep().

Armada
quelle
1
Es ist verdammt schlechter Code, Timer sollte anstelle von Schlaf verwendet werden, also ist es ein schlechtes Beispiel
ST3
12
@ ST3 - Ja, du hast recht. Mein Code ist schrecklich. Ich sollte mich das nächste Mal mehr anstrengen, wenn ich eine Endlosschleife mache.
Armada
1
@Frammo - hängt von Ihrem Betriebssystem ab, aber normalerweise so etwas wietimerService.scheduleRepeating (50, [] () { /* lots of code */ });
Periata Breatta
2
Es ist nichts Sauberes daran, eine Funktion wie sleep in einer
Greg
1
OMG, timerService.scheduleRepeating (50, [] () {}) ist einfach sooo viel einfacher zu tippen und zu verstehen als Sleep (50).
Cool Javelin
4

Die "für immer" -Schleife ist in eingebetteten Systemen als Hintergrundschleife beliebt. Einige Leute implementieren es als:

for (; ;)
{
 // Stuff done in background loop
}

Und manchmal wird es implementiert als:

while (TRUE /* or use 1 */)
{
 // Stuff done in background loop
}

Und noch eine andere Implementierung ist:

do
{
 // Stuff done in background loop
} while (1 /* or TRUE */);

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.

Thomas Matthews
quelle
8
Wenn ein Compiler für diese einen anderen Code generiert, ist es an der Zeit, den Compiler loszuwerden und einen aus den letzten zwei Jahrzehnten zu erhalten.
GManNickG
5
"Die Ausführungszeit für die Schleifen ist kein großes Problem, da diese Schleifen für immer weitergehen" - das klingt für mich so falsch.
Blindy
3
@Blindy - weil es falsch ist, ist der Bruchteil der Laufzeit, die für die Verarbeitung der Schleifenlogik aufgewendet wird, oder die Menge der Schleifenlogik pro nützlicher Arbeitseinheit von Bedeutung, von denen keine durch die Endlosschleife unterstützt wird
Ben Voigt
3

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 :)

nik
quelle
Geschwindigkeit ist mir wichtig. Besonders wenn es eine Optimierung gibt, die meinen Code unendlich oft beeinflusst.
Kowalski
2

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.

    for(int i=0;i<1000;i++) recursiveFunction(oneParam);

Wenn ich mir meiner Funktion sicher bin, konvertiere ich sie in eine Endlosschleife:

    for(;;) recursiveFunction(oneParam);
Ignacio Cortorreal
quelle
3
Die erste Schleife weist einen Syntaxfehler auf (ein Semikolon fehlt).
Jens
3
Ha! Damit demonstrieren die Nachteile von für (;;);)
Andrew