Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Break schlechter Programmierstil? (https://www.delphipraxis.net/13121-break-schlechter-programmierstil.html)

Phoenix 11. Dez 2003 13:16

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:

Zitat von Sanchez
Delphi-Quellcode:
  while NichtGefunden and (i < Count) do begin
    if Gefunden then begin
      NichtGefunden := false;
      MachWasDraus;
      i := i + 1;
    end;
  end;

Schliesslich macht die nix. Noch nichtmal den Counter erhöhen :)

Sanchez 11. Dez 2003 13:22

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

Phoenix 11. Dez 2003 13:31

Re: Break schlechter Programmierstil?
 
Negativ, Dein Zähler wird nur um eins erhöht, wenn das Element das richtige ist:
Delphi-Quellcode:
if Gefunden then begin
      NichtGefunden := false;
      MachWasDraus;
      i := i + 1;      // <-- hier, nur im if gefunden then... block
    end;
Will heissen: wenn nicht zufällig das erste Element schon das gesuchte ist bleibt er für immer darauf stehen.

Sanchez 11. Dez 2003 13:32

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:

jbg 11. Dez 2003 15:04

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

Robert Marquardt 11. Dez 2003 15:35

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.

Phoenix 11. Dez 2003 15:47

Re: Break schlechter Programmierstil?
 
Zitat:

Zitat von jbg
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.

Auch Du hattest keine for - Schleifen mit break abgebrochen. ;-)
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:
begin
   TuWas;
end;

procedure TuWas;
begin
   // nix zu tun
   if Status in [Sonderfall1, Sonderfall2] then
      exit;

   JetztTuWirklichWas;
end;
Das sollte natürlich nicht in jeder Methode stehen, aber ab und an kann das einem das Leben ganz schön vereinfachen.

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.

Robert Marquardt 11. Dez 2003 18:37

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.

SirThornberry 11. Dez 2003 18:53

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:
  if not OpenDialog1.execute then exit; //exit entspricht ja break nur das es nicht für schleifen ist
wobei

Delphi-Quellcode:
  if OpenDialog1.execute then
  begin
    [..]
  end;
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...

Robert Marquardt 11. Dez 2003 19:00

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.
Seite 2 von 3     12 3      

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