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.

Benutzer-Avatar
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.

Benutzer-Avatar
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

Benutzer-Avatar
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

Benutzer-Avatar
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.

1385880cookie-checkIst die Verwendung eines While-Blocks, um nichts zu tun, eine schlechte Sache?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy