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 true
muss 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 break
und continue
mag. Er schlug vor, stattdessen eine reguläre Schleife while
oder eine do ... while
Schleife zu verwenden.
Es scheint mir, dass die Verwendung von break
und continue
der 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 break
oder continue
und 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 break
und continue
mag 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 break
und continue
wä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
, return
oder throw
irgendwo da drin. Die Einführung einer zusätzlichen Variablen, die im Auge behalten werden muss, um einer break
oder auszuweichen, continue
ist 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 continue
Inneres gibt, um if
zu wissen, dass das break
nicht genommen wird.
dataIsValid
ist 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 expr
Auswertung false
die Schleife unterbrochen wird , ohne dass der Rest des Schleifenkörpers betrachtet werden muss.