Autor |
Beitrag |
Pow
      
Beiträge: 25
Win7
Borland Delphi 7
|
Verfasst: Do 22.07.10 12:56
Hallo,
ist es möglich bei einer for-Schleife den Zähler unter einer bestimmten Bedingung heruntersetzen zu lassen?
Ich gehe nämlich in einer for-Schleife in eine repeat-until-Schleife und wenn dort z.B. die Variable "Vorgang_abbrechen" durch einen Button gesetzt wird,
soll er durch continue von vorne anfangen, aber nicht den Zähler hochzählen, sondern den gleichen Durchlauf beginnen
Kann man sowas realisieren?
z.B.:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| for ii := 1 to [..] do begin if Vorgang_abbrechen = true then begin ii := ii - 1; end; Vorgang_abbrechen := false;
repeat [..] until Vorgang_abbrechen or [..]; if Auftrag_unterbrechen then begin break; end else if Vorgang_abbrechen then begin continue; end; | Moderiert von Narses: Topic aus Sonstiges (Delphi) verschoben am Do 22.07.2010 um 13:02
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Do 22.07.10 12:59
Ja, irgendwo hat im DF das einer mal reingehackt über Pointer usw, glaub ich. Aber prinzipiell: Nein, das is böse und wird aus gutem Grund vom Complier verboten. Aber wenn es dir hilft: Aus jeder for-Schleife kann man eine repeat-until oder while-Schleife machen.
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
Pow 
      
Beiträge: 25
Win7
Borland Delphi 7
|
Verfasst: Do 22.07.10 13:11
Oh.. ja richtig, danke für den Hinweis
Mit einer while-Schleife funktionierts natürlich
|
|
spawn89
      
Beiträge: 82
Erhaltene Danke: 7
Linux
CodeTyphon
|
Verfasst: Do 22.07.10 13:14
Ansonsten noch zur Vollständigkeit bzw zu Lernzwecken:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9:
| var i: Integer; begin for i := 1 to 1 do begin Integer(Pointer(@i)^) := i-1; ShowMessage('Aufruf Nr.: '+IntToStr(i)); end; end; |
|
|
thepaine91
      
Beiträge: 763
Erhaltene Danke: 27
Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
|
Verfasst: Do 22.07.10 13:16
So gehts auch ist aber letzendlich mehr oder weniger das selbe.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| procedure TForm1.Button1Click(Sender: TObject); var pt: ^integer; i: integer; begin for i := 0 to 99 do begin pt := @i; pt^ := 99; ShowMessage(inttostr(i)); end; end; |
|
|
Nersgatt
      
Beiträge: 1581
Erhaltene Danke: 279
Delphi 10 Seattle Prof.
|
Verfasst: Do 22.07.10 15:50
Wobei ich mich definitv dafür ausspreche, dass jeder, der solche Spielchen in produktivem Quellcode einbaut, geteert und gefedert wird. Außerdem wird ihm der PC entzogen und er darf bis ans Lebensende nur noch Basic auf einem VC20 programmieren
Was ich sagen will: Nimm ne While-Schleife und verwalte den Zähler komplett selbst. 
_________________ Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
|
|
glotzer
      
Beiträge: 393
Erhaltene Danke: 49
Win 7
Lazarus
|
Verfasst: Do 22.07.10 16:20
dumme frage, aber was ist so böse dran?
|
|
elundril
      
Beiträge: 3747
Erhaltene Danke: 123
Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
|
Verfasst: Do 22.07.10 17:42
Wurde damals in dem von mir erwähnten unbekannten Thread erklärt warum das schlecht ist, bitte zwing mich nicht ihn rauszusuchen. Ich hab nämlich keine Ahnung von wem der Beitrag war und welche Stichworte auf den Thread passen würden.
lg elundril
_________________ This Signature-Space is intentionally left blank.
Bei Beschwerden, bitte den Beschwerdebutton (gekennzeichnet mit PN) verwenden.
|
|
yogo
      
Beiträge: 121
Windowse, Linuxe
Delphi 3 Prof., D5 Enterprise, D6 Enterprise, Kylix, Delphi 2010
|
Verfasst: Do 22.07.10 18:14
Ist es nicht so, dass bei eingaschalteter optimierung schleifen insgeheim von hinten nach vorne gehen? (von 50 -> 1)
macht ja auch sinn, dann brauch man nur ein register mit dec zu verringern und nicht noch ein etra register für den vergleich nach eine subtraktion.
dec und jz
dann wäre der vermeintliche schritt nach hinten ein schritt nach vorne, oder lieg ich falsch?
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Do 22.07.10 22:02
Moin!
Der Compiler optimiert die Laufvariable nur dann, wenn du nicht darauf zugreifst. Wird die Laufvariable im Schleifenkörper verwendet, werden auch genau die bei den Grenzen angegebenen Werte erzeugt.
Allerdings zwingt man den Compiler auf diese Weise eine Register-Optimierung zu unterlassen (wenn ich das richtig verstanden habe, aber das kann BenBE sicher besser erklären  ).
Togal: es ist und bleibt schlechter Stil, weil es den Code weniger wartungsfreundlich und undurchsichtiger macht. Normalerweise rechnet man nicht damit, dass in einer for-Schleife die Laufvariable im Körper verändert wird.
IMHO ist es grade noch tolerierbar, eine for-Schleife zu verlassen, z.B. die klassische IndexOf-Methode:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7:
| function IndexOf(const Needle: String; Haystack: TStrings): Integer; begin for Result := 0 to Haystack.Count-1 do if (Haystack[Result] = Needle) then Exit; Result := -1; end; | Hier wird die Schleife lediglich abgebrochen - performant und trotzdem intuitiver Code.  Grundsätzlich würde ich immer davon abraten, schreibend auf die Laufvariable zuzugreifen.
cu
Narses
//EDIT: Redaktionelle Änderungen nach alzaimars Hinweisen.
_________________ There are 10 types of people - those who understand binary and those who don´t.
Zuletzt bearbeitet von Narses am Fr 23.07.10 09:36, insgesamt 2-mal bearbeitet
|
|
Nersgatt
      
Beiträge: 1581
Erhaltene Danke: 279
Delphi 10 Seattle Prof.
|
Verfasst: Fr 23.07.10 07:12
_________________ Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
|
|
spawn89
      
Beiträge: 82
Erhaltene Danke: 7
Linux
CodeTyphon
|
Verfasst: Fr 23.07.10 07:53
Break; und Exit; nutze ich auch sehr aktiv und das nicht ohne Grund.
Wenn ich wirklich so die Abfragen wie Nersgatt einbaun würde hätte ich oftmals zeilenlange Bedingungen, durch die später keiner mehr durchblickt.
Oder man müsste Bedingungen in weitere Unterfunktionen kapseln. 
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 23.07.10 08:22
Narses hat folgendes geschrieben : | ... rechnet man nicht damit, dass in einer for-Schleife die Laufvariable im Körper verändert wird.
... IMHO ist eine der wenigen Ausnahmen die klassische IndexOf-Methode:... |
Wo wird denn in der IndexOf-Methode die Laufvariable verändert?
Narses hat folgendes geschrieben : | ...Grundsätzlich würde ich immer davon abraten, die Laufvariable anzufassen. |
Wieso? Dann würdest Du ja jeden Array-Scan über eine WHILE-Schleife realisieren? Du meinst sicherlich "schreibend zugreifen".
Nersgatt hat folgendes geschrieben : | Sowas mache ich persönlich immer mit einer While-Schleife:... |
Wieso einfach, wenns auch umständlich geht.
Nersgatt hat folgendes geschrieben : | So sieht man schon am Schleifenkopf, zu welchen Bedingungen die Schleife terminieren wird und stößt nicht überraschenderweise auf ein Exit mitten im Schleifenkörper. |
Klar. Übersichtlicher gehts nicht. Was macht die Schleife nochmal? Ach ja.
"Solange i noch nicht am Ende ist und ein Resultat = -1 ist, soll was gemacht werden?.. ach und wenn dann die Nadel gefunden wurde, wird das Resultat auf die Laufvariable gesetzt und die wird dann erhöht. ... Aha.. Ach soooo.. und dann hört die While-Schleife ja auf, weil das Resultat nicht mehr -1 ist. Toller Trick." Tricks haben im Code nix zu suchen.
Hmm. Das ist mir Folgendes wirklich lieber: "Suche im Heuhaufen, bis Du die Nadel gefunden hast und hör dann auf zu suchen."
Das wäre die deutsche Übersetzung der For-Schleife, wobei der letzte Teil das 'überraschende Stoßen auf das EXIT' darstellt.
So ein "EXIT" ist aber höchstens so überraschend ("Huch!") wie ein 'inc(i)' oder ein nicht für möglich gehaltenes 'IF'.
_________________ Na denn, dann. Bis dann, denn.
|
|
thepaine91
      
Beiträge: 763
Erhaltene Danke: 27
Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
|
Verfasst: Fr 23.07.10 09:26
Ich bin für diese Variante:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function TForm1.IndexOf(const Needle, Haystack: Pointer): Integer; var sref: ^string; tsref: ^TStrings; label lbl; begin sref := Needle; tsref := Haystack; for Result := 0 to tsref^.Count - 1 do begin if tsref^[Result] = sref^ then goto lbl; end; lbl: end; |
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Fr 23.07.10 09:33
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
spawn89
      
Beiträge: 82
Erhaltene Danke: 7
Linux
CodeTyphon
|
Verfasst: Fr 23.07.10 09:36
|
|
thepaine91
      
Beiträge: 763
Erhaltene Danke: 27
Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
|
Verfasst: Fr 23.07.10 09:39
Das funktioniert hab es vorher getestet.
|
|
spawn89
      
Beiträge: 82
Erhaltene Danke: 7
Linux
CodeTyphon
|
Verfasst: Fr 23.07.10 09:42
Überleg mal was passiert wenn der string nicht enthalten ist.
Tja, das sieht man nicht mehr auf anhieb, da es mittlerweile schon an Code 'überquillt'.
btw: Kommt da nicht eine Compiler-Warnung?
|
|
thepaine91
      
Beiträge: 763
Erhaltene Danke: 27
Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
|
Verfasst: Fr 23.07.10 09:54
So ist es besser und hast recht ^^ das hab ich wirklich nicht bedacht
So kommt keine Meldung mehr vorher kam nur Result könnte undefiniert sein.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
| function TForm1.IndexOf(const Needle, Haystack: Pointer): Integer; label lbl; begin for Result := 0 to TStrings(Haystack^).Count - 1 do begin if Tstrings(Haystack^)[Result] = string(Needle^) then goto lbl; end; Result := -1; lbl: end; |
|
|
Jakob_Ullmann
      
Beiträge: 1747
Erhaltene Danke: 15
Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
|
Verfasst: Fr 23.07.10 11:07
was haltet ihr davon:
Delphi-Quelltext 1: 2: 3: 4: 5:
| for i := 1 to 20 do if i = 12 then asm dec i end; |
|
|