Ich bin ein Autodidakt. Ich habe vor ungefähr 1,5 Jahren angefangen zu programmieren. Jetzt habe ich angefangen, Programmierunterricht in der Schule zu haben. Wir haben Programmierkurse für 1/2 Jahr und werden jetzt noch 1/2 haben.
In den Klassen lernen wir, in C ++ zu programmieren (eine Sprache, die ich bereits gut kannte, bevor wir anfingen).
Ich hatte während dieses Kurses keine Schwierigkeiten, aber es gibt ein wiederkehrendes Problem, für das ich keine klare Lösung finden konnte.
Das Problem ist wie folgt (im Pseudocode):
do something
if something failed:
handle the error
try something (line 1) again
else:
we are done!
Hier ist ein Beispiel in C ++
Der Code fordert den Benutzer auf, eine Nummer einzugeben, bis die Eingabe gültig ist. Hiermit wird cin.fail()überprüft, ob die Eingabe ungültig ist. Wann cin.fail()ist truemuss ich anrufen cin.clear()und der cin.ignore()Lage sein, weiterhin eine Eingabe von dem Strom zu bekommen.
Mir ist bekannt, dass dieser Code nicht überprüft
EOF. Von den Programmen, die wir geschrieben haben, wird nicht erwartet, dass sie dies tun.
So habe ich den Code in einer meiner Aufgaben in der Schule geschrieben:
for (;;) {
cout << ": ";
cin >> input;
if (cin.fail()) {
cin.clear();
cin.ignore(512, '\n');
continue;
}
break;
}
Mein Lehrer sagte, dass ich das nicht benutzen sollte breakund continuemag. Er schlug vor, stattdessen eine reguläre Schleife whileoder eine do ... whileSchleife zu verwenden.
Es scheint mir, dass die Verwendung von breakund continueder einfachste Weg ist, diese Art von Schleife darzustellen. Ich habe tatsächlich eine ganze Weile darüber nachgedacht, aber nicht wirklich eine klarere Lösung gefunden.
Ich denke, er wollte, dass ich so etwas mache:
do {
cout << ": ";
cin >> input;
bool fail = cin.fail();
if (fail) {
cin.clear();
cin.ignore(512, '\n');
}
} while (fail);
Für mich scheint diese Version viel komplexer zu sein, da wir jetzt auch eine Variable haben, die aufgerufen wird fail, um den Überblick zu behalten, und die Überprüfung auf Eingabefehler zweimal statt nur einmal durchgeführt wird.
Ich dachte mir auch, dass ich den Code so schreiben kann (Missbrauch der Kurzschlussauswertung):
do {
cout << ": ";
cin >> input;
if (fail) {
cin.clear();
cin.ignore(512, '\n');
}
} while (cin.fail() && (cin.clear(), cin.ignore(512, '\n', true);
Diese Version funktioniert genau wie die anderen. Es wird nicht verwendet breakoder continueund der cin.fail()Test wird nur einmal durchgeführt. Es erscheint mir jedoch nicht richtig, die "Kurzschlussbewertungsregel" so zu missbrauchen. Ich glaube auch nicht, dass es meinem Lehrer gefallen würde.
Dieses Problem betrifft nicht nur die cin.fail()Überprüfung. Ich habe breakund continuemag dies für viele andere Fälle, in denen ein Satz von Codes wiederholt wird, bis eine Bedingung erfüllt ist, bei der auch etwas getan werden muss, wenn die Bedingung nicht erfüllt ist (wie das Aufrufen cin.clear()und cin.ignore(...)aus dem cin.fail()Beispiel).
Ich habe breakund continuewährend des gesamten Kurses weiter verwendet und jetzt hat mein Lehrer aufgehört, sich darüber zu beschweren.
Was ist deine Meinung dazu?
Glaubst du, mein Lehrer hat recht?
Kennen Sie einen besseren Weg, um diese Art von Problem darzustellen?
while (true)und sofort annehmen , dass es ein break, returnoder throwirgendwo da drin. Die Einführung einer zusätzlichen Variablen, die im Auge behalten werden muss, um einer breakoder auszuweichen, continueist kontraproduktiv. Ich würde argumentieren, dass das Problem mit dem Anfangscode darin besteht, dass die Schleife eine Iteration normalerweise nie beendet und dass Sie wissen müssen, dass es ein continueInneres gibt, um ifzu wissen, dass das breaknicht genommen wird.
dataIsValidist veränderlich. Um zu wissen, dass die Schleife korrekt beendet wird, muss ich überprüfen, ob sie gesetzt ist, wenn die Daten gültig sind, und ob sie zu keinem Zeitpunkt danach deaktiviert wird . In einer Schleife der Form do { ... if (!expr) { break; } ... } while (true);weiß ich, dass bei einer exprAuswertung falsedie Schleife unterbrochen wird , ohne dass der Rest des Schleifenkörpers betrachtet werden muss.