![]() |
Break schlechter Programmierstil?
Hallo,
in der heutigen Informatikstunde haben wollten wir einen spezifischen Wert aus einem Array suchen. Unser Lehrer nutzte hierzu eine WHILE schleife. Ich schlug hierrauf vor, das mit einer FOR schleife und einem Break; nach dem Finden des Wertes (bzw. des indexes) die schleife zu verlassen. Er meinte daraufhin, dass man das so nicht machen könne(oder solle), da Break "extrem schlechter" Programmierstil sei. Nun meine Frage: Ist da tatsächlich was dran? War die Benutzung von Break unter TurboPascal nun anders, sodass mein Lehrer das Break als schlechten Stil bezeichnet? mfG mirage228 |
Re: Break schlechter Programmierstil?
lol,
ich benutze Break nicht oft, aber ich benutze es und finde es nicht als schlechten Programierstil genauso exit, wobei ich exit wichtiger finde Gruß |
Re: Break schlechter Programmierstil?
Es ist schon so, das es nicht gerade zu einem guten Programmierstil gehört. Manchmal ermöglicht es aber eine übersichtlichere Konstruktion.
|
Re: Break schlechter Programmierstil?
Ich benutze break eigentlich regelmäßig in der Form, wie es Mirage beschrieben hat.
Ich hatte dabei nicht das Gefühl, dass diese Konstruktionen meinen Programmierstil runterziehen. Da gibts schlimmere Sachen, die mich ärgern, wenn ich später mal was modifiziere. |
Re: Break schlechter Programmierstil?
ka wieso das schlecht sein sollte, würde doch nur zeit kosten wenn man es nicht benutzt und die schleife ganz durchlaufen lässt ohne das es noch nötig ist
|
Re: Break schlechter Programmierstil?
Ob schlechter oder guter Stil liegt in so einem Fall auch immer daran, wofür man ein bestimmtes Konstrukt verwendet.
Würdest Du, wenn Du einen Countdown brauchst, eine normale Uhr nehmen und an der Stelle wo 0 sein soll einen Nagel ins Zifferblatt hauen um den Zeiger zu stoppen (break), oder gleich eine Sanduhr nehmen und nur so viel Sand einfüllen wie Du für den Countdown brauchst (while)? Eine For-Schleife ist nunmal dann das richtige Werkzeug, wenn Du für jedes (for each, wie es auch ab und zu woanders heisst) Element in der Schleife etwas bestimmtes tun willst. Man sucht aber nicht für jedes Element, sondern solange wie man es noch nicht gefunden hat. Deshalb ist bei einer sequentiellen Suche nunmal eine while - Schleife die richtige. Von daher würde ich Deinem Lehrer da in jedem Fall zustimmen: For / break für eine Suche ist schlechter Stil. |
Re: Break schlechter Programmierstil?
Ich finds einfach einfacher, wenn ich
Delphi-Quellcode:
schreibe als
for i:=0 to Count - 1 do begin
if gefunden then begin MachWasDraus; break; end; end;
Delphi-Quellcode:
zu schreiben. Wenns irgendeine plausible Erklärung gibt, while zu verwenden nehm ich halt while
while NichtGefunden and (i < Count) do begin
if Gefunden then begin NichtGefunden := false; MachWasDraus; i := i + 1; end; end; |
Re: Break schlechter Programmierstil?
Hrm..
Scheint, als hättest Du da was nicht ganz 100% optimiert :) Also wenn man das richtig macht sieht das so aus:
Delphi-Quellcode:
while not gefunden do
Suche; Machwas;
Delphi-Quellcode:
Und was ist nun besser?
for i := 0 to Count - 1 do
begin Suche; if gefunden then break; end; Machwas; |
Re: Break schlechter Programmierstil?
Zitat:
|
Re: Break schlechter Programmierstil?
Phoenix, wenn das element nicht gefunden wurde, ergibt das obere gnadenlos eine endlosschleife :-D
wir hatten das so gemacht, dass wir das ergebins erstmal auf 0 (ausserhalb des arrays) setzen und die while schleife maximal bis zu CONST n = 10000 (so lang ist der Array) laufen lassen. mfG mirage228 |
Re: Break schlechter Programmierstil?
In Suche wird gefunden auf true gestellt, wenn das Element gefunden wurde.
Alternativ kann man hier auch einen Counter mitführen der halt auch true zurückgibt wenn man am Ende der Elementliste ist. Allerdings ist die von Sanchez ist immer eine Endlosschleife: Zitat:
|
Re: Break schlechter Programmierstil?
Meine Version ist keine Endlosschleife.
Count ist die Anzahl der Elemente (z.B. length(Array) oder stringliste.count) und i ist der Zähler. i wird in jedem Schleifendurchgang um eins erhöht |
Re: Break schlechter Programmierstil?
Negativ, Dein Zähler wird nur um eins erhöht, wenn das Element das richtige ist:
Delphi-Quellcode:
Will heissen: wenn nicht zufällig das erste Element schon das gesuchte ist bleibt er für immer darauf stehen.
if Gefunden then begin
NichtGefunden := false; MachWasDraus; i := i + 1; // <-- hier, nur im if gefunden then... block end; |
Re: Break schlechter Programmierstil?
:oops: das muss ich wohl übersehen haben. Aber das diente sowieso nur zur Veranschaulichung und hat nie einen Kompiler zu gesicht bekommen :mrgreen:
|
Re: Break schlechter Programmierstil?
Bei so einfachen Beispielen ist die Benutzung von Break sicher nicht begründet. Das break ist eher für eine Schleife, in der mehr als nur eine Anweisung steht gedacht, wobei die restlichen Anweisungen bei einer bestimmten Bedingung nicht mehr ausgeführt und die Schleife verlassen werden soll.
Versuche mal folgenden Code ohne Break (und natürlich ohne goto) zu realisieren. Welcher der beiden Codes wird leichter zu lesen sein?
Delphi-Quellcode:
while (i < lCount) or (ri < rCount) do begin
if i < lCount then l := FLocalFL.Items[Integer(lList.Objects[i])] else begin // alle restlichen Remote-Dateien in die Delete-Listen while ri < rCount do begin if FRemoteFL.Items[Integer(rList.Objects[ri])].IsDir then delDirs.AddObject('-d' + rList[ri], rList.Objects[ri]) else delFiles.AddObject('-f' + rList[ri], rList.Objects[ri]); inc(ri); end; break; // und raus end; if ri < rCount then rl := FRemoteFL.Items[Integer(rList.Objects[ri])] else begin // alle restlichen Local-Dateien in die Add-Listen while i < lCount do begin if FLocalFL.Items[Integer(lList.Objects[i])].IsDir then addDirs.AddObject('+d' + lList[i], lList.Objects[i]) else addFiles.AddObject('+f' + lList[i], lList.Objects[i]); inc(i); end; break; // und raus end; if not DoCompare(l.Name, rl.Name) then begin // Datei suchen x := ri; while (x < rCount) and (not DoCompare(rList[x], l.Name)) do inc(x); if x = rCount then begin // nicht gefunden // Datei/Ordner hinzufügen if l.IsDir then addDirs.AddObject('+d' + l.Name, lList.Objects[i]) else addFiles.AddObject('+f' + l.Name, lList.Objects[i]); // neue Datei // LocalIndex dec(ri); // und ri am Ende nicht erhöhen end else begin // gefunden // Alle dazwischenliegenden Dateien löschen while ri < x do begin if FRemoteFL.Items[Integer(rList.Objects[ri])].IsDir then delDirs.AddObject('-d' + rList[ri], rList.Objects[ri]) else delFiles.AddObject('-f' + rList[ri], rList.Objects[ri]); inc(ri); end; // Daten holen rl := FRemoteFL.Items[Integer(rList.Objects[ri])]; end; end; if DoCompare(l.Name, rl.Name) then begin if l.IsDir and rl.IsDir then begin end // Verzeichnisse nicht überprüfen else if l.IsDir <> rl.IsDir then begin if rl.IsDir then begin // eine Datei ist ein remote Verzeichnis ??? -> remote Verzeichnis mit Subdirs löschen. delDirs.AddObject('-d' + rl.Name, rList.Objects[ri]); // RemoteIndex dir := rl.Name + '/'; len := length(dir); inc(ri); // Unterordner löschen while (ri < rCount) do begin rl := FRemoteFL.Items[Integer(rList.Objects[ri])]; if DoCompare(copy(rl.Name, 1, len), dir) then begin if rl.IsDir then delDirs.AddObject('-d' + rl.Name, rList.Objects[ri]) else delFiles.AddObject('-f' + rl.Name, rList.Objects[ri]); // RemoteIndex end else break; inc(ri); end; dec(ri); // und die Datei hinzufügen addFiles.AddObject('+f' + l.Name, lList.Objects[i]); // LocalIndex end else begin // ein Verzeichnis ist eine remote Datei ??? -> remote Datei löschen delFiles.AddObject('-f' + rl.Name, rList.Objects[ri]); // RemoteIndex // und das Verzeichnis hinzufügen addDirs.AddObject('+d' + l.Name, lList.Objects[i]); // LocalIndex end; end else begin // nur Dateien hier: update := False; if (FUpdateDate) then begin update := ((not FUpdateOnlyNewerDate) and (l.LastWriteTime <> rl.LastWriteTime)) or ((FUpdateOnlyNewerDate) and (l.LastWriteTime > rl.LastWriteTime)); end; if (FUpdateSize) and (l.Size <> rl.Size) then update := True; if update then updFiles.AddObject('*f' + l.Name, lList.Objects[i]); // LocalIndex end; // if end; // if inc(i); inc(ri); end; // while |
Re: Break schlechter Programmierstil?
Break ist nicht per se schlecht. In C z. B. sind die for und while Schleife sehr eng verwandt und Break ist dort voellig normal.
In Delphi ist die for Schleife konzeptionell deutlich anders als die while Schleife. Man sollte mit dem Break sparsam umgehen. Da es aber vorhanden ist, kann sein Gebrauch auch nicht falsch sein. Wichtig ist das man nicht zu Exit greift wenn Break reicht. Das macht die Programme leichter wartbar. Besonders haesslich finde ich es wenn man zum exzessiven Exit Stil greift und in kurzen Methoden erst mal alle Bedingungen mit Exit abweist. Das ist schwer verstaendlich. |
Re: Break schlechter Programmierstil?
Zitat:
Es mag vereinzelt tatsächlich Situationen geben, in denen man aus einer for - Schleife mit break aussteigen muss, aber solche Situationen sind recht selten. Fast noch seltener sind solche Dinge in einer while - Schleife, da man hier ja die break-bedingung meist noch in die Schleifenbedingung packen kann. Wie gesehen geht das aber auch nicht immer, deswegen braucht man schon solche Abbrüche. Sonst gäbe es das break ja auch nicht. Was das exit angeht: gerade bei Sonderbedingungen ist es schon nützlich.
Delphi-Quellcode:
Das sollte natürlich nicht in jeder Methode stehen, aber ab und an kann das einem das Leben ganz schön vereinfachen.
begin
TuWas; end; procedure TuWas; begin // nix zu tun if Status in [Sonderfall1, Sonderfall2] then exit; JetztTuWirklichWas; end; Das is allemal besser, als an zig einzelnen Stellen in denen die Methode aufgerufen wird jedesmal eine Abprüfung einzubauen, um den Aufruf zu verhindern. |
Re: Break schlechter Programmierstil?
Phoenix, dein Beispiel fuer Exit ist genau das was man nicht tun soll.
In so einer kurzen Funktion ist ein positives if leichter verstaendlich als ein Abweisen mit einer negativen Bedingung. |
Re: Break schlechter Programmierstil?
Wenn das schlechter programmierstil ist mit "break" dann schließ ich daraus das die Jedi-Programmierer schlechte Programmierer sind bzw. einen schlechten Stil haben weil das darin vorkommt.
Da steht in einem beispiel zum beispiel
Delphi-Quellcode:
wobei
if not OpenDialog1.execute then exit; //exit entspricht ja break nur das es nicht für schleifen ist
Delphi-Quellcode:
viel schöner ist. Find das zwar selbst mit den breaks und exits nicht so schon aber manchmal lässt sichs einfach nicht vermeiden oder es macht ungerechtfertigt viel aufwand es anders zu schreiben was einen dann niemand bezahlen würde...
if OpenDialog1.execute then
begin [..] end; |
Re: Break schlechter Programmierstil?
Da hast du ganz recht das die JVCL viel schlechten Code enthaelt.
Ich beschaeftige mich ja auch damit das auszumerzen. 16 Megabyte Sourcen umzugraben dauert aber seine Zeit. Im Augenblick zentralisiere ich die resourcestrings, dann geht es wieder mit der Ueberarbeitung des Stils weiter. Wenn du es bei kurzen Funktionen gleich richtig machst dann dauert es auch nicht laenger als die schlechte Version und beide werden gleich bezahlt. |
Re: Break schlechter Programmierstil?
Hallo mirage228,
ja, ich dachte immer ein sauberes BASIC "GOTO" sei ein schlechter Programmierstil, weil es Spagetti Code erlaubt. "Break" und "Continue" hingegen erlauben dagegen ein sauberes Verlassen einer "for" oder "while" Schleife und der Compiler streikt, wenn sie außerhalb definierter Befehle verwendet werden. Na ja, wie dem auch sei, die Entwickler und dein Lehrer werden sich was mit ihrem Handeln und Aussagen gedacht haben. bye Claus |
Re: Break schlechter Programmierstil?
Moin...
Ein Argument (vielleicht ist es ja auch keins) fehlt mir hier eigentlich noch... Ist es nicht so, dass For-Schleifen in Pascal wesentlich performanter sind als While-Schleifen? Berichtigt mich ruhig... Bin immer bereit was zu lernen! Wenn ich also aus einer langen Liste, Array, etc. das passende Gegenstück raussuchen soll (Klassischer Fall: ID und Bezeichnung) dann mache ich das mit einer For-Schleife aufgrund des definierten Endes im Fehlerfall (Länge des Arrays). Nun ist es aber völliger Unsinn wenn der entsprechende Eintrag gefunden wurde, die Schleife weiterlaufen zu lassen. Wenn ich das mit einer While-Schleife realisiere muss ich Die Schleife verlassen bei "Found OR End of Array". der Code dafür ist wahrscheinlich länger und nicht so übersichtlich wie bei der For-Schleife... Aber es ist wohl auch so, dass jeder seinen eigenen Style finden muss und dann versuchen sollte, dass auch andere ihn verstehen. Bis denne... [EDIT] Ausserdem sind Lehrer - Informatiklehrer bilden da keine Ausnahme - oft ziemlich rechthaberisch. Egal wie offensichtlich ihr Irrtum ist. Unabhängig von der "Break"-Frage jetzt [/EDIT] |
Re: Break schlechter Programmierstil?
Eine for-Schleife ist performanter als eine while-Schleife, da die Endebedingung nur einmal ausgewertet wird.
|
Re: Break schlechter Programmierstil?
Zitat:
Ich finde for mit break manchmal übersichtlicher, manchmal while. Dann sollte man die übersichtlichere Variante nehmen. Wobei "übersichtlicher" subjektiv sein kann, aber darüber lässt sich streiten. Manchmal ist auch die eine Lösung viel einfacher zu tippen. Dann soll man halt die nehmen, die einem grade einfällt und nicht die Zeit damit verschwenden, wie die ander Lösung aussähe! Bei "inner loops" bei nem zeitintensiven Alogo, der die Abbruchbedingung nur selten erfüllt, ist aber die for-Schleife aus Performance-Gründen vorzuziehen. Da hab ich lieber nicht so leserlichen Code, der dafür (im Extremfall) bis zu doppelt so schnell ist. Die while-Schleifen sind der Wink mit dem Zaunpfahl, wenn man den Code nicht kennt, und sich fragt, ob jetzt z.B. das ganze Array durchgegangen wird. Aber eine for Schleife tuts auch und ist nicht unbedingt schlechter! |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:23 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz