Menu

Do-While-Schleife in C: Syntax, Beispiele und wann man sie nimmt

Cs Schleife mit dem Rumpf zuerst: wie do-while einen Durchlauf vor der Prüfung garantiert, warum sie mit einem Semikolon endet, die Menü- und Wiederholungsmuster, für die sie gemacht ist, und worin sie sich von einer schlichten while-Schleife unterscheidet.

Diese Seite enthält ausführbare Editoren - bearbeiten, ausführen und Ausgabe sofort sehen.

Die Schleife, die immer einmal läuft

Eine while-Schleife prüft, bevor sie handelt, sie kann also null Mal laufen. Das ist meist richtig. Manchmal ist es genau falsch: Du kannst nicht wissen, ob du eine Aufforderung wiederholen musst, bevor du sie gezeigt hast, und du kannst die Eingabe eines Benutzers nicht beurteilen, bevor du etwas gelesen hast. do-while verschiebt die Prüfung ans Ende, der Rumpf läuft also zuerst und die Bedingung entscheidet nur, ob es noch einmal weitergeht.

Die Bedingung i < 5 ist von Anfang an falsch. Die while-Schleife läuft null Mal; die do-while-Schleife läuft genau einmal. Das ist der gesamte Unterschied zwischen beiden.

Syntax, und dieses Semikolon

do {
    // Rumpf - läuft immer mindestens einmal
} while (condition);

Die Reihenfolge liest sich, wie sie abläuft: tue den Rumpf, solange die Bedingung noch gilt, tue ihn erneut.

Das abschließende Semikolon nach der schließenden Klammer ist Pflicht. do ... while (bed); ist eine Anweisung, und C-Anweisungen enden mit Semikolons. Lass es weg, und der Compiler liest weiter und meldet dann irgendwo darunter einen Syntaxfehler - weshalb der eigentliche Fehler oft mehrere Zeilen von der Zeile entfernt ist, auf die der Fehler zeigt.

Das ist auch die eine Stelle in C, an der while (bed); mit einem Semikolon korrekt ist statt ein Bug. In einer schlichten while-Schleife erzeugt dieselbe Zeichensetzung einen leeren Rumpf und meist eine Endlosschleife; hier schließt sie ein do ab.

Klammern sind bei einem Rumpf aus einer Anweisung optional, aber schreibe sie wie bei jeder anderen C-Kontrollstruktur trotzdem.

Das Muster zur Eingabeprüfung

Dafür wurde do-while entworfen. Du musst etwas lesen, bevor du sagen kannst, ob es akzeptabel ist, das Lesen muss also vor der Prüfung passieren:

Die Schleife liest weiter, bis ein Wert durchkommt, und dieselbe Bedingung, die einen schlechten Wert ablehnt, fordert auch den nächsten Durchlauf an. Als while geschrieben müsste das Lesen zweimal auftauchen - einmal vor der Schleife, um die Bedingung zu füllen, und einmal am Ende des Rumpfes -, und genau diese Doppelung beseitigt do-while.

Mit echter Eingabe würde der Rumpf stattdessen scanf aufrufen:

int age;
do {
    printf("Gib dein Alter ein (1-120): ");
    if (scanf("%d", &age) != 1) {
        while (getchar() != '\n') { }   /* die schlechte Zeile verwerfen */
        age = -1;                        /* einen weiteren Durchlauf erzwingen */
    }
} while (age < 1 || age > 120);

Beachte das innere while, das den Rest der Zeile abräumt. Wenn scanf nicht umwandeln kann, sitzt der störende Text weiterhin im Eingabepuffer und jeder spätere Lesezugriff scheitert ebenfalls daran - eine Schleife, die sich ewig dreht und die Aufforderung ausgibt. Ihn zu leeren gehört zum Muster.

Das Menümuster

Die andere klassische Verwendung: die Optionen zeigen, eine Wahl lesen, darauf reagieren und wiederholen, bis der Benutzer beendet. Das Menü muss erscheinen, bevor es eine Wahl zu prüfen gibt.

Ein break innerhalb des switch beendet das switch, nicht die Schleife - ein Punkt, bei dem Genauigkeit sich lohnt, da beide dasselbe Schlüsselwort verwenden. Hier endet die Schleife, weil choice != 4 falsch wird. Wolltest du die Schleife aus dem switch heraus verlassen, wären return oder eine Flag-Variable der Weg; break allein schafft es nicht.

Ein garantierter erster Durchlauf kann ein Bug sein

Weil der Rumpf vor jeder Prüfung läuft, verarbeitet do-while bereitwillig Daten, die es nicht gibt:

/* BUG: gibt a[0] aus, auch wenn n gleich 0 ist */
int i = 0;
do {
    printf("%d\n", a[i]);
    i++;
} while (i < n);

Mit n == 0 liest das a[0] auf einem leeren Array - undefiniertes Verhalten. Jede Schleife über eine Sammlung, die leer sein könnte, will ein while oder ein for, deren Prüfung zuerst kommt.

Die Faustregel: Nimm do-while nur, wenn ein Lauf mit null Iterationen aufgrund der Natur des Problems unmöglich ist, nicht bloß in der Praxis unwahrscheinlich. Einen Benutzer zu fragen, zu würfeln, bis ein Zielwert auftaucht, einen Kandidaten zu erzeugen und zu prüfen - das lässt sich wirklich nicht vor dem ersten Durchlauf beurteilen. Eine Liste zu durchlaufen kann das nicht behaupten.

break und continue in einer do-while-Schleife

Beide funktionieren, und continue hat eine wissenswerte Wendung: Es springt zur Bedingungsprüfung, nicht an den Anfang des Rumpfes.

Das i++ am Anfang des Rumpfes läuft bei jedem Durchlauf, auch bei denen, die continue abkürzt, die Schleife rückt also weiter vor. Setze die Aktualisierung hinter ein continue, und die Schleife hängt - dieselbe Falle wie bei while-Schleifen.

break verlässt die Schleife sofort und überspringt die Bedingung vollständig.

Zwischen den drei Schleifen wählen

Cs drei Schleifen sind gleich mächtig; die Wahl geht darum, welche die Absicht ausspricht.

for        ein Zähler, seine Grenze und seine Schrittweite gehören zusammen - "n-mal"
while      wiederholen, bis eine Bedingung sich ändert, vielleicht auch gar nicht - "bis"
do-while   dasselbe, aber der erste Durchlauf ist garantiert - "mindestens einmal"

In der Praxis ist do-while mit großem Abstand die seltenste der drei. Die meisten Schleifen zählen entweder oder müssen den leeren Fall behandeln, und beide wollen die Prüfung oben. Greife zu do-while, wenn du dich dabei ertappst, eine Anweisung direkt vor einer while-Schleife zu wiederholen, um deren Bedingung zu füllen - diese Doppelung ist das Signal.

Häufig gestellte Fragen

Wie schreibt man eine do-while-Schleife in C?

do { rumpf } while (bedingung); - der Rumpf kommt zuerst, die Prüfung danach, und die ganze Anweisung endet mit einem Semikolon. Der Rumpf läuft immer mindestens einmal und wiederholt sich dann, solange die Bedingung ungleich null ist.

Was ist der Unterschied zwischen while und do-while in C?

Wo die Prüfung sitzt. Eine while-Schleife prüft die Bedingung vor dem ersten Durchlauf, kann also null Mal laufen. Eine do-while-Schleife prüft danach, läuft also immer mindestens einmal. Wähle do-while nur, wenn dieser garantierte erste Durchlauf wirklich das ist, was das Problem braucht.

Warum braucht eine do-while-Schleife am Ende ein Semikolon?

Weil do ... while (bed); eine einzelne Anweisung ist und wie jede andere C-Anweisung mit einem Semikolon abgeschlossen wird. Lässt du es weg, entsteht ein verwirrender Syntaxfehler, der auf die folgende Zeile zeigt, weil der Compiler nach dem Rest der Anweisung weiterliest.

Wann sollte ich eine do-while-Schleife benutzen?

Wenn der Rumpf laufen muss, bevor du überhaupt wissen kannst, ob du wiederholen sollst: ein Menü zeigen, bevor du eine Wahl liest, erneut nachfragen, bis die Eingabe gültig ist, oder einen Wert erzeugen und ihn dann prüfen. Wenn die Bedingung vorab geprüft werden kann, sagt es eine while-Schleife klarer.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S