Mit break aus for(..;..;..) raus?
-
Simon2 schrieb:
while(irgendeine Bedingung && !(erste Operation erfolgreich)) zweite OperationWieso nicht ?
Mach bitte aus erste Operation was zwei- oder dreizeiliges.

-
Also was mir einfallen würde, ist daß du einfach die Schleife undefiniert abbrichst und der resltiche Code nicht ausgeführt wird. Aber wenn du genau weisst, warum du an diesem Punkt rausspringst ist ja egal...
-
Jester schrieb:
Was machste mit einem
while(irgendeine Bedingung) { if(erste Operation erfolgreich) break; zweite Operation }Es gibt keinen Zusammenhang zwischen "irgendeine Bedingung" und "erste Operation". Aber beide beenden die Schleife. Was soll sowas ?

-
Naja, hier gibt es wieder zwei Parteien. Ich bleibt dabei und benutze break da, wo es mir passend erscheint

-
merker schrieb:
Jester schrieb:
Was machste mit einem
while(irgendeine Bedingung) { if(erste Operation erfolgreich) break; zweite Operation }Es gibt keinen Zusammenhang zwischen "irgendeine Bedingung" und "erste Operation". Aber beide beenden die Schleife. Was soll sowas ?

Sowas schreibt man meistens wenn "irgendeine Bedingung" keine Seiteneffekte hat, "erste Operation" aber schon. In dem Fall halte ich es so wie es oben steht auch für wesentlich klarer als wenn beides im Schleifenkopf steht.
Sich auf die Kurzschlusslogik zu verlassen damit bestimmte Teile eines Ausdrucks mit boolschen Operatoren in einer Schleifenbedingung nichtmehr ausgeführt werden halte ich für Mist, vor allem wenn diese Teile eben Seiteneffekte haben.
Pfui Pfui Pfui.@OP: nein, technische Gründe gibt es nicht.
-
Jester schrieb:
Simon2 schrieb:
while(irgendeine Bedingung && !(erste Operation erfolgreich)) zweite OperationWieso nicht ?
Mach bitte aus erste Operation was zwei- oder dreizeiliges.

bool erste_operation_erfolgreich() { ... }4 zeilen

-
klar kann man die schleifen immer in eine while umformen
aber was ist wenn da sehr viel verschiedener code ist - das wird dann schon schwererfor(unsigned int i=0; i<1000000000; ++i) { . . . . . . . . if(jes) { . . . . if(jes2) { . . . . break; } else if(aha) { . . . if(jes2) { . . . . break; } } . . . . . . . } . . . }
-
Einfache Regel: Alle Abbruchbedingungen, die man ohne Probleme im "Schleifenkopf" einbringen kann, bringt man dort ein. Alle anderen nicht.
Ein Zwang sorgt nur für unleserlichen Code! Viel wichtiger ist es kurze Funktionen (also auch schleifen) zu schreiben. Wenn eine Schleife mehr als (sagen wir mal) 5 Zeilen hat, verliert man ohnehin schnell die Übersicht und sollte lieber Unterfunktionen benutzen.
Die Vorstellung von "Single Entry/Single Exit" ist in Programmiersprachen mit Exceptions eh schädlich, da man darüber keine Kontrolle mehr hat (außer man zwingt sich künstlich eine auf).
-
Ich will nicht kleinelich sein, aber wenn ich schon break verwende dann mach ich's so dass es auch auffällt und schreib's auf eine eigene Zeile.
while (irgendeine Bedingung) { if (erste Operation erfolgreich) break; zweite Operation; }Eine generelle Antwort auf die Frage "break/continue/return" oder nicht wird's glaube ich nicht geben.
Die Verwedung
- muss korrenkt sein
- sollte performant sein
- sollte gut lesbar seinDann ist es imho o.k.
Wenn man alles im Schleifenkopf machen kann würde ich's auch tun wenn die Ausdrücke nicht zu komplex sind.
Möglichst vermeiden würde ich allerdings break nach Konditionalen die über einem Laufindex operieren, so im Sinne von "Wenn der nächste Wert soundso dann break".
Damit führt man den Leser in die Irre.Grüsse
*this
-
otze schrieb:
mein info lehrer hat mir auch sowas gesagt, er meinte, dass die funktionen dann nicht mehr mathematisch validierbar sind *schulterzuck*
Halte ich persönlich für Unsinn. ZB sind in C/C++ while-Schleifen ja grundsätzlich nicht mathematisch validierbar. Wenn es so wäre, würde man wohl eher zur for-Schleife greifen.
Was die eigentliche Frage betrifft, so sollte man immer die Laufbedingung nutzen, um die Schleife zu verlassen. Wenn das allerdings nicht so einfach möglich ist, spricht nichts gegen break.
-
groovemaster schrieb:
Halte ich persönlich für Unsinn. ZB sind in C/C++ while-Schleifen ja grundsätzlich nicht mathematisch validierbar.
Dazu zwei Fragen:
- Was genau bedeutet für euch "mathematisch validierbar"?
- Warum sind while-Schleifen in C++ grundsätzlich nicht validierbar?
-
rüdiger schrieb:
Einfache Regel: Alle Abbruchbedingungen, die man ohne Probleme im "Schleifenkopf" einbringen kann, bringt man dort ein. Alle anderen nicht.
Ganz genau.
Die einzige Alternative ist sowieso nur den Code mit Abfragen auf
loop_broken, skip_iterationetc. zu sprenkeln. Genau so "komplex", dafür unübersichtlicher und ineffizienter.
-
Kuldren schrieb:
Ich wollte lediglich wissen ob es (technische) gründegibt break nicth zu benutzen

war ein argument der lehrer und ich verstehe nicht welch technische gründe das haben könnte...ich könnte mir da wenn dann sowas vorstellen:
while (a()) { myclass * b = new myclass b->abc() [...]// ganz viel code mit b if (b->ende()) break; [...]//nochmal viel code delete b; }Kann in längeren Schleifen zu schwehr auffindbaren Speicherlecks führen.
=> throw, break, continue können zu Speicherleks führen, wenn "rohe" Pointer im Spiel sind. Ein throw zu verhindern ist, wenn Biblioteken im Spiel sind eher schwehr.Das Problem entfällt natürlich mit std::tr1::smart_pointer & co.
-
Jester schrieb:
groovemaster schrieb:
Halte ich persönlich für Unsinn. ZB sind in C/C++ while-Schleifen ja grundsätzlich nicht mathematisch validierbar.
Dazu zwei Fragen:
- Was genau bedeutet für euch "mathematisch validierbar"?
- Warum sind while-Schleifen in C++ grundsätzlich nicht validierbar?Da war was mit einer Invarianten. Aber so genau weiss ich es jetzt auch nicht mehr

-
darthdespotism schrieb:
Kuldren schrieb:
Ich wollte lediglich wissen ob es (technische) gründegibt break nicth zu benutzen

war ein argument der lehrer und ich verstehe nicht welch technische gründe das haben könnte...ich könnte mir da wenn dann sowas vorstellen:
while (a()) { myclass * b = new myclass b->abc() [...]// ganz viel code mit b if (b->ende()) break; [...]//nochmal viel code delete b; }Kann in längeren Schleifen zu schwehr auffindbaren Speicherlecks führen.
=> throw, break, continue können zu Speicherleks führen, wenn "rohe" Pointer im Spiel sind. Ein throw zu verhindern ist, wenn Biblioteken im Spiel sind eher schwehr.Das Problem entfällt natürlich mit std::tr1::smart_pointer & co.
Das Problem gab es nie seit Gott damals std::auto_ptr erfunden hat, und uns Menschen erlaubt selbst ähnliche Klassen (RAII) zu schreiben.
-
hustbaer schrieb:
darthdespotism schrieb:
Das Problem entfällt natürlich mit std::tr1::smart_pointer & co.
Das Problem gab es nie seit Gott damals std::auto_ptr erfunden hat, und uns Menschen erlaubt selbst ähnliche Klassen (RAII) zu schreiben.
Eben das habe ich mit meinem letzten Satz aussagen wollen. Es gibt aber immer noch jede Menge Leute die so mit Pointern umgehen
(vielleicht gibts performance-Gründe, vll nicht)
-
Also ich hab mir zur Gewohnheit gemacht in SChleifen break zu benutzen, wenn ich wirklich schnell raus will ohne noch viele Operationen durhczuführen... Nur sollte man wissen was man tut. Dann gibt es auch keine technischen Probleme.
-
Jester schrieb:
Was genau bedeutet für euch "mathematisch validierbar"?
validieren -> prüfen
Wie geht das bei einer Schleife, die mehrere Laufbedingungen hat ?
Wie geht das bei einer Funktion, die so eine Schleife enthält ?"Logik" alleine ist nicht ausreichend.

-
Naja, mutable State is nicht gut für "Beweisbarkeit".
Eine einfache Schleife ala "for x = 0 to 100" lässt sich meist auch relativ einfach "mathematisch" darstellen.
Wenn man allerdings etwas hat ala...bool foo = true; for (int x = 0; (x <= 100) && foo; x++) { // ... if (...) foo = false; }...dann hat man oft schon ein Problem. Die Korrektheit der Schleife oben lässt sich allerdings genauso schwer oder einfach beweisen wie die folgendermassen umgeformte:
for (int x = 0; x <= 100; x++) { // ... if (...) break; }Einfacher zu beweisen wird es bloss wenn man ausschliesslich Abbruchbedingungen verwendet die es einem erlauben mit wenig Aufwand die Anzahl der Durchläufe zu bestimmen.
-
rüdiger schrieb:
Einfache Regel: Alle Abbruchbedingungen, die man ohne Probleme im "Schleifenkopf" einbringen kann, bringt man dort ein. Alle anderen nicht.
Ein Zwang sorgt nur für unleserlichen Code! Viel wichtiger ist es kurze Funktionen (also auch schleifen) zu schreiben. Wenn eine Schleife mehr als (sagen wir mal) 5 Zeilen hat, verliert man ohnehin schnell die Übersicht und sollte lieber Unterfunktionen benutzen....

Genau so meinte ich das.Jester schrieb:
Simon2 schrieb:
while(irgendeine Bedingung && !(erste Operation erfolgreich)) zweite OperationWieso nicht ?
Mach bitte aus erste Operation was zwei- oder dreizeiliges.

Was meinst Du damit ? Mehrere Funktionsaufrufe ? Ein Funktionsaufruf mit 20 Parametern ? ...
In jedem Fall wirst Du es auf einen bool herunterbrechen und den kannst Du ebensogut in die Abbruchbedingung (und ggf. zusätzlich in ein if for "zweite Operation") packen.
Aber (wie ich auch schon gesagt habe) irgendwann KANN die Komplexität ein break sinnvoller machen. Trotzdem halte ich die Regel "break nur im absoluten Ausnahmefall" für sinnvoll, weil sie einen dazu zwingt, sich ein paar mehr Gedanken über Übersichtlichkeit und Komplexität zu machen.
Wer break als Defaultweg ansieht, findet sich schnell in der Wartungshölle wieder.
(Auch Schleifen mit break sind nicht wirklich übersichtlich ... aber im Extremfall vielleicht übersichtlicher als ihre "breaklosen Pendants")Gruß,
Simon2.