C Gibt es eigentlich Schleifen die nicht mit break vorzeitig beendet werden können?

@array123
Leider ist deine Frage ziemlich sinnlos.
break beendet eine Schleife. Ansonsten ist es kein break. Punkt.
Es gibt auch kein if-else, das nicht "Wenn-dann" ist.
Es gibt ja nur wenige Art von Schleifen. Je nach Sprache sind es eigentlich nur while bzw. do-while und for. Und für jede dieser Schleifen ist break und continue definiert.

Damit es nicht ganz wertlos ist:
In manchen Sprachen gibt es das continue. Damit wird der aktuelle Schleifendurchlauf an der derzeitigen Stelle beendet und sofort der nächste Durchlauf der Schleife begonnen.
 
Ich erinnere mich an meinen IT-Lehrer:
Wenn ihr Break in einer Schleife braucht, habt ihr die Bedingung nicht korrekt gesetzt oder eure Annahme war falsch.
Im Nachhinein:
Das abbrechen einer Schleife ist nur sinnvoll, wenn sonst Speicher, Zeit oder anderes volläuft.

Aber im Grunde hatte meine Lehrer damals recht:
Wer eine Schleife unterbrechen muss hat schlampig programmiert.
 
  • Gefällt mir
Reaktionen: Piak
array123 schrieb:
Da habe ich mich aber gefragt, ob es Schleifen gibt, die sich nicht automatisch beenden und trotzdem die Schleife durchlaufen und am Ende erst abbrechen.
auch wenn ich es nicht ganz verstehe, in Java gibt es noch continue um den einzelnen Schleifendurchlauf zu skippen, aber die Schleife danach weiter auszuführen. Die Semantik und der Zweck von break ist aber eben die gesamte Schleife abzubrechen. Wenn das eine Programmiersprache nicht so machen würde, dann wäre es "seltsam"
 
array123 schrieb:
Da habe ich mich aber gefragt, ob es Schleifen gibt, die sich nicht automatisch beenden und trotzdem die Schleife durchlaufen und am Ende erst abbrechen.
Es wird doch bei jeder Iteration immer die Bedingung geprüft, dessen Wahrheitswert kannst allein du beeinflussen. Auch ein break braucht man fast nie. Die Schleife läuft bis zur Abbruchbedingung.

Hast du die Schleifendefinition verstanden?
 
array123 schrieb:
Da habe ich mich aber gefragt, ob es Schleifen gibt, die sich nicht automatisch beenden und trotzdem die Schleife durchlaufen und am Ende erst abbrechen.
Die Antwort darauf ist relativ simpel: Nein. Schleifen die sich "nicht automatisch beenden" können nicht "am Ende erst abbrechen" - das ist ein inhaltlicher Widerspruch.

Du hast hier glaube konzeptuell ein Problem. Willst du die Schleife vorzeitig beenden, nimmst du break. Ansonsten wartest du, bis die Schleifenbedingung nicht mehr erfüllt ist. Es gibt zudem auch mehrere Arten von Schleifen. Die berühmtesten sind:
for-Schleifen: Wird ausgeführt, solange die for-Bedingung erfüllt ist.
while-Schleifen: Wird ausgeführt, solange die while-Bedingung erfüllt ist
repeat-until-Schleife: Wird ausgeführt, solange die until-Bedingung nicht erfüllt ist, jedoch mindestens einmal.

Schleifen enden also, wenn ihre Bedingungen erfüllt sind. Ein break ist dafür da, um Schleifen vorzeitig zu beenden. Es erleichtert so gesehen das Programmieren, weil man nicht die Schleifenbedingung manipulieren muss.
 
  • Gefällt mir
Reaktionen: R00kie
MichiSauer schrieb:
Aber im Grunde hatte meine Lehrer damals recht:
Wer eine Schleife unterbrechen muss hat schlampig programmiert.
Das ist kompletter Quatsch. Ohne break müsste man sich in vielen Fällen mit einer Hilfsvariable (z.B. “abort) behelfen, die man nicht nur in der Schleifenbedungung sondern auch oft noch im Schleifenrumpf abfragen müsste. Das macht den Code auf jeden Fall unübersichtlicher und in vielen Fällen auch langsamer.

Mechanismen um Schleifen vorzeitig zu verlassen, wie break, return oder auch throw sind nicht ohne Grund eingeführt wurden. Das ist besser als sich mit goto zu behelfen, wie es das Ur-Pascal gemacht hat. Andererseits kann goto verwendet werden, um alle anderen Varianten zu simulieren
 
  • Gefällt mir
Reaktionen: mental.dIseASe, ni-sc, Rexaris und eine weitere Person
Welche Folgen das hat, wenn man die Frage nur in den Titel packt 🤣

Ich interpretiere die Frage so, dass der TE sichergehen möchte, dass die Verwendung von break immer das erwartete Ergebnis bringt und die Schleife verlassen wird.
Die C-Programmierer werden sagen: Logo, geht ja nicht anders!
Aber ich denke hier liegt es etwas an der Unerfahrenheit vom TE und der Neugierde zu den weiten von C, die er eventuell noch nicht erkundet hat.

Die Frage dürfte vermutlich so zu verstehen sein:
'Mir sind diese Schleifen bekannt, die durch ein "break" korrekt beendet werden:
  • while
  • for

Gibt es andere Arten von Schleifen, die eine Besonderheit sind und aufgrund dieser Besonderheit das "break" ignorieren?'

Und die Antwort darauf ist eben: Nein, da gibt es keine anderen Schleifen - jedenfalls keine die von C als Schleifen zu verstehen sind. Alle Schleifen berücksichtigen das break und werden abgebrochen.

Ich bin aus dem Thema C zu lange raus, weist der Compiler nicht sogar darauf hin, wenn man Kommandos verwendet, die an der Stelle nichts zu suchen haben - z.B. ein break in einem If-Statement?
 
  • Gefällt mir
Reaktionen: TomH22
Auch wenn wir uns damit vom Thema entfernen:
goto ist Spaghetti Code und habe ich glücklicherweise seit altem VB oder cmd/bash Scripts nicht mehr gesehen ;)
Tatsächlich versuche ich auch break so oft es geht zu vermeiden. Bei Fehlerbehandlung ist ein beak aber ganz nützlich.
Mir fällt gerade kein konkretes Beispiel ein, bei dem man eine Hilfsvariable oder ein break bräuchte. Irgendwie entscheidet man doch wo man das break auslösen will und das kann auch als Abbruchbedingung nutzen. Allerdings sollte man für Performance auch darauf achten, ob die Bedingung bei jedem Durchlauf geprüft werden muss, oder nur abhängig von einer anderen Bedingung.
Generell würde ich aber statt break lieber ein return nutzen um einen Status zurückzugeben, aber das ist vermutlich Geschmackssache.

Da die Frage aber nur allgemein interessehalber ist und nicht, wie von vielen vermutet, eine Anforderung für ein konkretes Programmierproblem, wäre meine Antwort:
Generell ist mir in C keine Schleife bekannt, die nicht mir break unterbrochen werden kann.
 
  • Gefällt mir
Reaktionen: R00kie
R00kie schrieb:
Ich interpretiere die Frage so, dass der TE sichergehen möchte, dass die Verwendung von break immer das erwartete Ergebnis bringt und die Schleife verlassen wird.
Die C-Programmierer werden sagen: Logo, geht ja nicht anders!
So habe ich das auch verstanden, und mich auch schon amüsiert, was Leute hier alles hineininterpretieren.
Ich habe auch schon völlige Anfänger im Programmieren ausgebildet, und wenn jemand da gerade seine ersten kleinen Schritte macht, können schon sehr abstruse Fragestellungen auftreten. Und Google hilft dann in diesen Fällen auch nur begrenzt, da eben dann keine Antworten kommen, die den Kontext des "völligen Anfängers" berücksichtigen.
Renegade334 schrieb:
Mir fällt gerade kein konkretes Beispiel ein, bei dem man eine Hilfsvariable oder ein break bräuchte
Klassisches Beispiel ist eine Schleife die von irgendeinem Stream liest (File, socket, etc.) und mittendrin gibt es einen Fehler (z.B. weil die Netzverbindung unterbrochen ist). Meist hat man ja eine while Schleife, die das reguläre Ende (z.B. feof(f) im Falle einer Datei) prüft. Das könnte man dann in while(!feof(f) && !error) umwandeln.
Dann muss man error vorher mit false initialisieren und in der Schleife irgendwann auf true setzen (z.B. mit error= fread(...)>0; ) Falls hinter dem fread noch Statements kommen, die vom Erfolg abhängen, braucht man ggf. noch sowas wie if(!error) { ... do something ... }

Ein break kann in diesem Fällen die Sache einfacher machen, allerdings löst es ggf. nicht das Problem, dass man hinterher noch erfolgsabhängig irgendwelche Dinge machen muss, weswegen man die error Variable trotzdem braucht.
In eher "archaischen" Sprachen wie C sind solche Fehlerbehandlungen immer irgendein Gebastel, was schnell unübersichtlich wird. Moderne Sprachen mit Exception Handling (try/catch, etc.) und automatischen Management von Objekt Lebenszyklen erlauben da elegantere und weniger fehleranfällige Lösungen.
Dann mache ich im Fehlerfall einfach ein "throw", und kann im Exception Handler ggf. aufräumen.

Andere typischer Anwendungsfall für break ist irgendeine Suchschleife.

Renegade334 schrieb:
Generell würde ich aber statt break lieber ein return nutzen um einen Status zurückzugeben, aber das ist vermutlich Geschmackssache.
Das geht immer dann, wenn Du eben nichts mehr aufräumen musst. Im obigen Beispiel wird man ggf. noch die Datei mit fclose schließen wollen/müssen.

Das ist de Vorteil wenn man C++ und z.B. std::fstream verwendet: Der Stream Destructor schliesst die Datei automatisch wenn das fstream Objekt "out-of-scope" geht. Da kann man dann wirklich einfach mit return rausspringen.
Renegade334 schrieb:
goto ist Spaghetti Code und habe ich glücklicherweise seit altem VB oder cmd/bash Scripts nicht mehr gesehen
Gerade in C, wo man eben keine automatischen Destruktoren, Exception Handling, etc. hat, kann ein bewusster goto Einsatz übersichtlicher und sicherer sein.

Ich löse das mit einem "error_cleanup" Block am Ende einer Funktion, der alle belegten Ressourcen aufräumt, dann ein return <errorcode> macht.

Man muss sich immer über eines klar sein: Progrmmierprinzipen und z.B. Coding Styles sind kein Selbstzweck, sondern sollen wartbaren, übersichtlichen Code produzieren. Wen in speziellen Fällen die Verletzung eines Prinzips (z.B. "kein goto verwenden), zu besseren Code führt. ist das wichtiger als das sklavischen Einhalten eines Style-Guides.
 
  • Gefällt mir
Reaktionen: Wechsler und R00kie
array123 schrieb:
gramm auf eines dieser breaks zutrifft und die Bedingung erfüllt ist, beendet er die Schleife automatisch.
Da habe ich mich aber gefragt, ob es Schleifen gibt, die sich nicht automatisch beenden und trotzdem die Schleife durchlaufen und am Ende erst abbrechen.
Du meinst sowas in der Art?
C:
...

int abbrechen = 0;

for_while_schleife( [ ... ] ) {
 
  if( [gut_1] )
     ;
  else
     abbrechen++;

  if( [gut_2] )
     ;
  else
     abbrechen++;


  if(abbrechen)
     break;
}
...
 
Zuletzt bearbeitet:
scooter010 schrieb:
Dann schau dir mal Assembler an. Nur sind es dort bedingte Sprünge, aber ebenso schwer zu lesen. Bei Assembler muss das aber so.
dem widerspreche ich aber vehement... kein code MUSS unverständlich sein... selbst in assembler hast du die möglichkeit zu kommentieren und ein schönes "bilderbuch" aus dem code zu machen, sodass es sogar (ohne abwertend wirken zu wollen, ledigleich ein beispiel zu einem völlig anderen arbeitsfeld der gleichen branche) ein webdesigner versteht...
 
MichiSauer schrieb:
Aber im Grunde hatte meine Lehrer damals recht:
Wer eine Schleife unterbrechen muss hat schlampig programmiert.
Ist das so? Ich mache sehr vieles sowieso direkt mit map/reduce/filter, aber wenn wir mal rein bei Schleifen bleiben, was ist, wenn ich z.B. wissen will, ob eine Person vermisst wird?

Code:
def somebody_missing?(persons)
  persons.each do |person|
    if person.missing?
      return true
    end
  end
  return false
end
Gut, ich sehe ein, da ist kein break :D. Aber macht das für dich einen Unterschied? Die Schleife wird ja frühzeitig verlassen. Wie würde man das umbauen, so dass es besser ist und die Schleife nicht frühzeitig verlassen wird?
 
Doch, Assembler ist immer deutlich schwieriger zu lesen als der gleiche Code in einer Hochsprache. Deswegen wurden ja Hochsprachen entwickelt. Sachen, die in ner Hochsprache vielleciht nur eine Zeile sind, ergeben im Assembler auch mal 20 Anweisungen und Sprungbefehle (+x Befehle/Byte) und das x ergibt sich auch noch dynamisch aus dem Code. Assembler kann IMHO nicht gut lesbar UND effizient in der Ausführung sein. Wenn es gut lesbar sein soll, verwende ich Sprungbefehle etc. die die Lesbarkeit fördern. Ein Compiler optimiert gnadenlos auf die effizienz.
 
  • Gefällt mir
Reaktionen: BeBur
TomH22 schrieb:
Klassisches Beispiel ist eine Schleife die von irgendeinem Stream liest (File, socket, etc.) und mittendrin gibt es einen Fehler (z.B. weil die Netzverbindung unterbrochen ist).
Das war ja auch mein explizites Beispiel :)

scooter010 schrieb:
Dann schau dir mal Assembler an. Nur sind es dort bedingte Sprünge, aber ebenso schwer zu lesen. Bei Assembler muss das aber so.
Musste ich leider oft genug. Das hat meine Abneigung dagegen nur verstärkt.
Ich sage auch nichts dagegen, dass der Code beim Übersetzen zu Sprüngen wird. Wenn man die ganzen Abstraktionen auflöst muss das spätestens bei Registern so sein, aber deswegen muss man das nicht in seinen Programmen nutzen. Dafür sorgt der Compiler schon.

Allerdings hat jede Mechanik irgendwo seine Berechtigung.
 
MichiSauer schrieb:
Wenn ihr Break in einer Schleife braucht, habt ihr die Bedingung nicht korrekt gesetzt oder eure Annahme war falsch.

Das habe ich in der Schule auch mal so gelernt und habe das am Anfang meines Berufslebens auch noch so sklavisch durchgezogen. Wenn man das so dogmatisch durchzieht, leidet aber irgendwann die Übersichtlichkeit/Lesbarkeit und damit die Wartbarkeit. Und Wartbarkeit ist mir inzwischen fast immer wichtiger als fast alles andere, auch bei fremdem, zu reviewendem Code. Da gehen dann auch mal break, continue, throw oder return in meiner Java-Welt. :)
 
mental.dIseASe schrieb:
Das habe ich in der Schule auch mal so gelernt. [..]Wenn man das so dogmatisch durchzieht, leidet aber irgendwann die Übersichtlichkeit/Lesbarkeit und damit die Wartbarkeit. [...] Da gehen dann auch mal break, continue, throw oder return in meiner Java-Welt. :)

Nix dagegen einzuwenden.
Solange man versucht es zu vermeiden, ist ja alles OK. Nur werden die Abbruchbedingungen heute halt oft ausschließlich über break definiert und das ist halt in 99% der Fälle unnötig, wenn man die Abbruchbedingungen der Schleife vorher ordentlich definiert.
 
MichiSauer schrieb:
Abbruchbedingungen heute halt oft ausschließlich über break definiert und das ist halt in 99% der Fälle unnötig
Hier wäre ich vorsichtig. Es ist mehr als gültig, wenn man eine Schleife zum Beispiel aus Performance-Gründen vorzeitig beendet, wenn man bereits alle Informationen hat die man braucht. Breaks sind etwas Gutes und nichts, was man vermeiden sollte.

Schlecht ist in der Regel nur eine Schleife, die ohne Break nie abbricht.

Schleifen kann man für vieles verwenden. Als Endlosschleife um ein Programm am Leben zu lassen, um über Daten drüberzulaufen und vermutlich noch andere Sachen die mir nicht einfallen.

Wie so oft kommt es drauf an. Eine Abbruchbedingung halte ich für notwendig, aber Breaks sind nichts schlechtes.
 
  • Gefällt mir
Reaktionen: DefconDev
MichiSauer schrieb:
wenn man die Abbruchbedingungen der Schleife vorher ordentlich definiert.
kannst du das bitte etwas ausführen ?

tRITON schrieb:
label: jmp label; über inline
Ich fand die Erwähnung von Rekursionen recht gut, weil sie nicht ohne weiteres durch breaks verlassen werden können. Allerdings zählen diese nicht zu den Schleifen 🙂. Warum ist Stoff für einen anderen Thread.
 
Zuletzt bearbeitet:
Zurück
Oben