Ist die Verwendung eines While-Blocks, um nichts zu tun, eine schlechte Sache?
Lesezeit: 5 Minuten
Ich arbeite gerade die Übungen in ‘The C Programming Language’ durch. Hier ist eine meiner Lösungen:
int c;
while ((c=getchar()) != EOF) {
if (c == ' ') {
while ((c = getchar()) == ' ')
{} // do nothing?
putchar(' ');
}
putchar(c);
}
Ich habe einige Lösungen gefunden hier die ganz anders sind als meine und eine zusätzliche Variable verwenden, um zu verfolgen, was vor sich geht, während ich nur eine While-Schleife verwende, um durch alle Leerzeichen zu springen. Meine Lösung fühlt sich etwas chaotisch an, da es etwas hackish erscheint, eine While-Schleife mit nichts zwischen den geschweiften Klammern zu haben. Ich frage mich, ob es gute Gründe gibt, dies nicht zu tun? Danke für jeden Rat 🙂
Sie müssen sich Gedanken darüber machen, was passiert, wenn die innere While-Schleife auf EOF trifft. Im Moment geben Sie wahrscheinlich als letztes Zeichen das Zeichen 0xFF (y-Umlaut) aus. Es wäre auch besser lesbar, wenn der Körper der äußeren Schleife eingerückt wäre.
– Jonathan Leffler
15. Januar 2009 um 5:52 Uhr
Überhaupt nicht – ich glaube, Sie werden in K&R solche Do-Nothing-Loops finden, also ist das so offiziell, wie es nur geht.
Es ist eine Frage der persönlichen Präferenz, aber ich bevorzuge meine Nichtstun-Schleifen wie diese:
while(something());
Andere ziehen es vor, dass das Semikolon in einer separaten Zeile steht, um die Tatsache zu unterstreichen, dass es sich um eine Schleife handelt:
while(something())
;
Wieder andere ziehen es vor, die Klammern ohne Inhalt zu verwenden, wie Sie es getan haben:
while(something())
{
}
Es ist alles gültig – Sie müssen nur den Stil auswählen, der Ihnen gefällt, und dabei bleiben.
Ich neige dazu, ein “Continue” in eine leere Schleife zu setzen: “while (foo) Continue;”. Dies macht die No-Op-Natur der Schleife für den Leser klarer, denke ich, aber das ist ein sehr kleines stilistisches Problem.
– Benutzer25148
15. Januar 2009 um 9:17 Uhr
Nie daran gedacht. Gute Idee liw.fi!
– Jmucchiello
15. Januar 2009 um 9:38 Uhr
In einem anderen Thread wird darauf hingewiesen, dass der Google Styleguide beides offiziell empfiehlt {} oder continue;da ein Semikolon allein wie das Ende einer do-while-Schleife aussehen könnte. google-styleguide.googlecode.com/svn/trunk/…
– Endolith
8. Februar 2012 um 15:24 Uhr
Ich denke, es ist vollkommen akzeptabel.
Ich würde es entweder schreiben:
//skip all spaces
while ((c = getchar()) == ' ') {}
um deutlich zu machen, dass diese eine Codezeile eine Sache tut.
Oder ich würde es so schreiben:
while ((c = getchar()) == ' ') {
//no processing required for spaces
}
damit es mit dem restlichen Format Ihres Codes übereinstimmt.
Ich persönlich bin kein Fan von der
while ((c = getchar()) == ' ');
Format. Ich denke, es ist zu einfach, das Semikolon zu übersehen.
+1 Ich habe eine ähnliche Meinung zum Semikolon gepostet, aber Ihre war ausführlicher.
– Alex Lymann
15. Januar 2009 um 5:11 Uhr
Kein kompetenter C-Programmierer schreibt Eingabeschleifen, die nicht auf EOF testen.
– Jim Balter
16. Februar 2014 um 4:40 Uhr
Ihre Frage “Ist es schlecht, einen While-Block zu verwenden, um nichts zu tun?” kann auch in Bezug auf die Verschwendung von CPU-Zyklen beantwortet werden. In diesem Fall ist die Antwort “Nein”, da der Prozess schläft, während er darauf wartet, dass der Benutzer ein Zeichen eingibt.
Der Prozess wird erst aktiviert, nachdem ein Zeichen eingegeben wurde. Dann findet der Test statt, und wenn der Test bestanden wird, dh c == ‘ ‘, geht der Prozess wieder schlafen, bis das nächste Zeichen eingegeben wird. Dies wiederholt sich, bis ein Nicht-Leerzeichen eingegeben wird.
Cebjyre
Nun, wenn Sie die leeren geschweiften Klammern wirklich nicht mögen, können Sie diese innere Schleife umgestalten
while (c == ' ') {c = getchar();}
Dies kostet jedoch einen zusätzlichen Vergleich, daher wäre eine Do-While-Schleife besser.
schlank
EIN while das bringt wohl nichts ist Eine schlechte Sache:
while(!ready) {
/* Wait for some other thread to set ready */
}
… ist eine wirklich, wirklich, teure Art zu warten – es wird so viel CPU verbrauchen, wie das Betriebssystem ihr gibt, und zwar so lange ready ist falsch und stiehlt CPU-Zeit, mit der der andere Thread nützliche Arbeit leisten könnte.
Wie auch immer Ihre Schleife ist nicht nichts tun:
while ((c = getchar()) == ' ')
{}; // skip
… weil es ruft getchar() bei jeder Iteration. Wie alle anderen zugestimmt haben, ist das, was Sie getan haben, in Ordnung.
Was ist eine kostengünstige Möglichkeit zum Blockieren?
– Endolith
4. Februar 2012 um 15:25 Uhr
Wenn Sie auf einen anderen Thread warten müssen, dann müssen Sie auf einen anderen Thread warten … sonst gibt es nicht viel zu tun, oder?
– Dwanderson
22. Februar 2017 um 3:18 Uhr
@dwanderson Wenn Sie auf einen anderen Thread warten müssen, sollten Sie verwenden Thread.wait() und Thread.notify().
– schlank
22. Februar 2017 um 8:37 Uhr
{}; ist gefährlich. (google nach sonst baumeln) Ich würde vorschlagen {;} stattdessen.
– Wildpässer
22. Februar 2017 um 16:30 Uhr
Dustin
Ich glaube nicht, dass das Verfahren ist, aber Ihre Formatierung ist ziemlich seltsam. Es ist nichts falsch mit:
/* Eat spaces */
while ((c = getchar()) == ' ');
(das heißt, zeigen Sie an, dass es absichtlich keinen Körper gibt)
Was ist eine kostengünstige Möglichkeit zum Blockieren?
– Endolith
4. Februar 2012 um 15:25 Uhr
Wenn Sie auf einen anderen Thread warten müssen, dann müssen Sie auf einen anderen Thread warten … sonst gibt es nicht viel zu tun, oder?
– Dwanderson
22. Februar 2017 um 3:18 Uhr
@dwanderson Wenn Sie auf einen anderen Thread warten müssen, sollten Sie verwenden Thread.wait() und Thread.notify().
– schlank
22. Februar 2017 um 8:37 Uhr
{}; ist gefährlich. (google nach sonst baumeln) Ich würde vorschlagen {;} stattdessen.
– Wildpässer
22. Februar 2017 um 16:30 Uhr
Charly Martin
Der kanonische Weg – seit jeher gebräuchlich, siehe z. B. das Lyoner Buch – ist
while(condition) // Here's the whole thing
; // empty body.
Tatsächlich wird im Allgemeinen die Konvention „Halbfarbe auf einer separaten Zeile“ für eine Nullanweisung verwendet. Sie werden zum Beispiel gelegentlich sehen
if( condition-1)
;
else if (condition-2)
stmt;
else {
// do stuff here
}
Es ist viel ungewöhnlicher, aber zeigt sich entweder wo Bedingung-1 ist sehr kompliziert, also wollen Sie es nicht negieren und Verwirrung riskieren, oder wo der Code innerhalb eines Zolls seiner Lebensdauer von Hand optimiert wurde, so dass Sie den häufigsten Fall zuerst wollen.
Das
while(condition) ;
Form ist sklavisch zu vermeiden, denn das ist ein häufiger und ärgerlicher Tippfehler: Sie sollten klarstellen, dass Sie es absichtlich getan haben. Leere Klammern
while(condition){
}
oder seine Varianten, sind ebenfalls problematisch, weil sie entweder nicht genug auffallen oder schlimmer noch zu anderen Tippfehlern führen.
13858800cookie-checkIst die Verwendung eines While-Blocks, um nichts zu tun, eine schlechte Sache?yes
Sie müssen sich Gedanken darüber machen, was passiert, wenn die innere While-Schleife auf EOF trifft. Im Moment geben Sie wahrscheinlich als letztes Zeichen das Zeichen 0xFF (y-Umlaut) aus. Es wäre auch besser lesbar, wenn der Körper der äußeren Schleife eingerückt wäre.
– Jonathan Leffler
15. Januar 2009 um 5:52 Uhr