![]() |
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. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:26 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