Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Befehl zum verlassen einer For-Schleife


Lord-Shakir - Mi 31.08.05 13:11
Titel: Befehl zum verlassen einer For-Schleife
Hallo Leutz,

Ich hab mir mal wieder ein kleines Programm gebastelt...

unter anderem is da ne for schleife drin.
jetzt möchte ich da ne if-schleife reinbringen, die etwas abfragt und im else fall die forschleife verlässt.

also (beispiel):


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
for i:=1 to 300 do
  if (x < edit1.text) or
     (y < edit2.text) 
    then
      begin
        x:=x+1;
        y:=y+5;
      end
     else ??? <---hier soll dann die forschleife verlassen werden
end;


gibt es so einen befehl?

MfG Felix

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.
Moderiert von user profile iconChristian S.: Topic aus Sonstiges verschoben am Mi 31.08.2005 um 14:16


noidic - Mi 31.08.05 13:12

1. Es gibt keine If-Schleifen ;)

2. Der Befehl, den du suchst, heisst break.


Christian S. - Mi 31.08.05 13:25
Titel: Re: Befehl zum verlassen einer For-Schleife
Hallo!

Mit Deiner if-Abfrage wirst Du wahrscheinlich sowieso nicht allzu viel Freude haben, da Du eine Zahl (x oder y) nicht mit einem String (edit1.text oder edit2.text) vergleichen kannst. StrToInt oder StrToFloat (je nachdem wie x und y deklariert sind) dürften da Deine Freunde sein.

Grüße
Christian


Amateur - Mi 31.08.05 13:54

genau.. die beiden haben recht.. was mich ma interessieren würde: für was braucht man so ne if abfrage? ich komm net hinter den sinn.....
erklär ma bitte was das fürn prog is... interessiert mich echt mal.
oder war das einfach nur ma so zum lernen?


Lord-Shakir - Mi 31.08.05 14:03

ich hab nicht gross drüber nachgedacht, was ich da für ein beispiel hinpinsel.. ^^

ich habe einfach nur schnell was hingetippt, dass mein problem erläutern sollte.
hier ein etwas fehlerfreieres bespiel (der if-ABFRAGE :D):


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
for i:=1 to 300 do  
  if (x < strtoint(edit1.text)) or  
     (y < strtoint(edit2.text))   
    then  
      begin  
        x:=x+1;  
        y:=y+5;  
      end  
     else ??? <---hier soll dann die forschleife verlassen werden  
end;


@Amateur: das programm soll solange einen wert um einen faktor erhöhen, bis der wert grösser ist als ein edit-wert. d.h. das programm dividiert eigendlich nur :wink: (ich frage mich gerade selber, wofür ich das eigendlich schreibe... :? )

Moderiert von user profile iconGausi: Code- durch Delphi-Tags ersetzt.


Gausi - Mi 31.08.05 14:10

probier mal break


Kroni - Mi 31.08.05 15:41

Break; ist unschön, du kannst das ganze doch mit einer while bzw repeat schleife machen!

z.B:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
i:=0;
while (i<300or (not deine bedingung) 
 begin
 inc(i);
 if (x < strtoint(edit1.text)) or(y < strtoint(edit2.text)) then begin x:=x+1; y:=y+5end;
 end;

Dann brauchst du kein hässliches Break


Heiko - Do 01.09.05 05:26

Bei diesem Beispiel kann man allerdings davor schon die Schleifendurchläufe ermitteln, da man es davor berechnen kann.
Aber du könntest noch x:=x+1 durch inc(x) und y:=y+5 durch inc(y, 5) ersetzten.


JRegier - Do 01.09.05 05:54

user profile iconKroni hat folgendes geschrieben:

Dann brauchst du kein hässliches Break


Also ich finde immer Exit häßlich! Aber Break benutze ich schon!

Aber sagt mal, ist es nicht besser Exit zu vermeiden?
also einfach dann ein not davor und dann alles in begin end; setzen!


LigH - Do 01.09.05 08:11

Sicher lassen sich Break und Exit normalerweise vermeiden.

Aber nicht um jeden Preis. Und der Preis wäre beispielsweise eine extrem komplexe, verschachtelte Bedingung, oder mehrere tief nach rechts verschachtelte bedingte Blöcke. Das muss nicht immer übersichtlicher sein.

Des weiteren halte ich ein Break bei relativ komplexen Abbruchbedingungen noch für eine halbwegs saubere Sache, denn nicht immer kann man schon im Kopf einer Schleife entscheiden, ob sie komplett durchlaufen muss/darf, manchmal entscheidet sich das auch an Zwischenergebnissen - da möchte ich mal jemanden sehen, der dort ohne künstliches Verlassen auskommt.

Man muss nur immer darauf achten, dass durch das Verlassen nicht irgendwelche angefangene Arbeit unvollendet liegen gelassen wird (z.B. eine geöffnete Datei nicht mehr geschlossen wird).

Eine mögliche Alternative wäre dafür auch: "try - finally - end", und "Abort" für das vorzeitige Verlassen, damit im "finally"-Block noch aufgeräumt werden kann. Ausnahmefehler (Exceptions) muss man nicht verfluchen, man kann sie sich auch geschickt zu Nutze machen. Für manche Leute erfordert das aber anscheinend jede Menge Überwindung! :lol:


Kroni - Do 01.09.05 15:25

Na ja try finally usw finde ich auch unschön, man kann sowas normalerweise durch überlegen vermeiden.....
Genausp wie n Break; in dem Beispiel....das war ja ne "einfache" schleife, und dann kann man besser ne while schleife nehmen bzw repeat, je nachdem, was man gerade braucht, anstatt dann ne for zu nehmen mit nem break;drin.....
Ist meine Meinung...^^


j-a-n@gmx.de - Do 01.09.05 15:39

user profile iconKroni hat folgendes geschrieben:
Na ja try finally usw finde ich auch unschön, man kann sowas normalerweise durch überlegen vermeiden.....


Da muss ich jetzt doch noch mal nachhacken....
wie kann ich beispielsweise das try/finally hier vermeiden:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
db := TDatabase.Create(nil);
try
  db.connected := False;
  db.DatabaseName := 'kaufmann';
  db.DriverName := 'STANDARD';
  db.HandleShared:= true;
  db.Params.Clear;
  db.Params.Add('Path=' + pfad);
  db.connected := True;

  adrarttable := TTable.create(nil);
  try 
    adrarttable.DatabaseName := db.DatabaseName;
    adrarttable.Active:=False;
    adrarttable.Filtered := False;
    adrarttable.TableName := 'AdrArt';
    adrarttable.Open();

    adrarttable.first();
    shipfor.Clear();
    while not adrarttable.eof do begin
      shipfor.AddItem(adrarttable.fieldbyname('adressart').asstring,
        TString.create(adrarttable.fieldbyname('art').asString));
  
      adrarttable.Next();
    end;
  finally
    adrarttable.close();
    freeandnil(adrarttable);
  end;
finally
  db.close();
  freeandnil(db);
end;


Delete - Do 01.09.05 15:44

Gar nicht. Da gehört es einfach hin. Da kann Kroni noch so viel überlegen, er wird da keine andere Lösung finden.


LigH - Do 01.09.05 22:21

So ist es: Man kann Exception-Handling nicht vollkommen vermeiden. Windows ist ein Multi-Threading-fähiges Betriebssystem. Im Allgemeinen kann ein Programmablauf für eine Zeitscheibe zu jeder Zeit unterbrochen werden, und in der Zwischenzeit kann ein anderes Programm alles mögliche veranstalten, was vorherige Prüfungen unwirksam macht.

Beispiele:

Dein Programm prüft, ob genug RAM frei ist, und stellt fest: Ja, genug frei.
--- Thread-Wechsel
Ein anderes Programm belegt ein paar Hundert MB RAM.
--- Thread-Wechsel
Dein Programm versucht, viel Speicher zu belegen, und scheitert, weil er inzwischen voll ist.

Oder:

Dein Programm prüft, ob eine Datei auf der Platte vorhanden ist; Ergebnis: Ja, sie ist vorhanden.
--- Thread-Wechsel
Ein anderes Programm löscht die Datei.
--- Thread-Wechsel
Dein Programm versucht, die Datei zu öffnen, und scheitert, weil sie inzwischen gelöscht wurde.

Solche Probleme lassen sich haufenweise konstruieren. Deshalb verstehe ich nicht, warum manche Leute regelrecht krankhaft, fast paranoid, an der Vermeidung von try-Blöcken interessiert sind. Zugegeben: In einer engen Schleife sind sie vermutlich eher langsam. Aber solange ein Programm nicht gerade zeitkritische Funktionen durchführen muss, sollte man sich nicht scheuen, ihre Vorteile zu nutzen.


ManuelGS - Do 01.09.05 22:52

Zitat:
Deshalb verstehe ich nicht, warum manche Leute regelrecht krankhaft, fast paranoid, an der Vermeidung von try-Blöcken interessiert sind.

Wahrscheinlich weil der Quelltext dadurch unübersichtlich wird.


Delete - Do 01.09.05 23:29

Eigentlich eher das Gegenteil. Ihc kann die Ausnahmefehler zentral an einer Stelle verarbeiten.


LigH - Do 01.09.05 23:31

Unübersichtlich werden Quelltexte nur, wenn man sie nicht ordentlich formatiert. Ansonsten kann ich mir nicht vorstellen, dass die Krämpfe, die man zum Umgehen von solchen Strukturen zusammenbasteln müsste, wirklich wesentlich übersichtlicher wären als ein sauberes Exception-Handling.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
if ... 
then begin
  if ...
  then begin
    if ...
    then begin
      ...
    end
    else begin
      ...
    end;
  end
  else begin
    if ...
    then begin
      ...
    end
    else begin
      ...
    end;
  end;
end
else begin
  if ...
  then begin
    if ...
    then begin
      ...
    end
    else begin
      ...
    end;
  end
  else begin
    if ...
    then begin
      ...
    end
    else begin
      ...
    end;
  end;
end;

oder

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
try
  try
    ...
  except
    on E1:EException1
    do begin
      ...
    end;
    on E2:EException2
    do begin
      ...
    end;
    on E3:EException3
    do begin
      ...
    end;
    on E4:EException4
    do begin
      ...
    end;
  end;
finally
  ...
end;


uall@ogc - Do 01.09.05 23:33

wenn jetzt noch jedes begin in eine extra zeile kommen würde, könnte man das ja so übernehmen


LigH - Do 01.09.05 23:45

Na ja - ich persönlich mag nicht gern "then/else" und "begin" untereinander schreiben, das verschwendet erstens eine Zeile, und stört mir zweitens etwas die Übersicht: Mir ist es irgendwie wichtiger, dass man über jedem "end" sieht, wozu der ganze Block gehört. Zu einem "begin" gehört ein "end" ja (fast) immer, das ist uninteressant - aber immer erst an das Ende einer Zeile schauen zu müssen, ob da hinten nun ein "then" oder "else" oder "do" steht, während das zugehörige "end" vorn steht, nervt mich doch etwas.

Aber das ist wieder mal persönlicher Geschmack. :roll: :wink:


adfontes - Fr 02.09.05 11:10

wie schon gesagt is persönlicher geschmack, aber wenn dus so machst, sollte da ja auch noch ne gewissen übersicht drin sein, dass du die zugehörigkeit von deinem end; auch klar erkennen kannst, geht mir zumindest so:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
begin
  if ... then
    begin
      ...
      if ... then
        begin
          ...
          if ... then
            begin
              ...
            end
          else
            begin
              ...
            end;
        end
      else
        begin
          ...
        end;
    end
  else
    begin
      ...
    end;
end.