Autor Beitrag
Pow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25

Win7
Borland Delphi 7
BeitragVerfasst: 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.:
ausblenden 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;  // das funktioniert an dieser Stelle nicht, weil der Compiler meckert
             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 user profile iconNarses: Topic aus Sonstiges (Delphi) verschoben am Do 22.07.2010 um 13:02
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: 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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 25

Win7
Borland Delphi 7
BeitragVerfasst: Do 22.07.10 13:11 
Oh.. ja richtig, danke für den Hinweis :)

Mit einer while-Schleife funktionierts natürlich
spawn89
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 82
Erhaltene Danke: 7

Linux
CodeTyphon
BeitragVerfasst: Do 22.07.10 13:14 
Ansonsten noch zur Vollständigkeit bzw zu Lernzwecken:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Do 22.07.10 13:16 
So gehts auch ist aber letzendlich mehr oder weniger das selbe.
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: 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 :D
Was ich sagen will: Nimm ne While-Schleife und verwalte den Zähler komplett selbst. :D

_________________
Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
glotzer
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 393
Erhaltene Danke: 49

Win 7
Lazarus
BeitragVerfasst: Do 22.07.10 16:20 
dumme frage, aber was ist so böse dran?
elundril
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 3747
Erhaltene Danke: 123

Windows Vista, Ubuntu
Delphi 7 PE "Codename: Aurora", Eclipse Ganymede
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 121

Windowse, Linuxe
Delphi 3 Prof., D5 Enterprise, D6 Enterprise, Kylix, Delphi 2010
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: 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 user profile iconBenBE 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:
ausblenden 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. :idea: Grundsätzlich würde ich immer davon abraten, schreibend auf die Laufvariable zuzugreifen.

cu
Narses

//EDIT: Redaktionelle Änderungen nach user profile iconalzaimars 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1581
Erhaltene Danke: 279


Delphi 10 Seattle Prof.
BeitragVerfasst: Fr 23.07.10 07:12 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:

IMHO ist eine der wenigen Ausnahmen die klassische IndexOf-Methode:
ausblenden 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;


Sowas mache ich persönlich immer mit einer While-Schleife:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
function IndexOf(const Needle: String; Haystack: TStrings): Integer;
var i : Integer;
begin
  i := 0;
  Result := -1;
  while (i <= Haystack.Count - 1and (result = -1do
  begin
    if (Haystack[i] = Needle) then
      Result := i;
    inc(i);
  end;
end;

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.

Jens

_________________
Gruß, Jens
Zuerst ignorieren sie dich, dann lachen sie über dich, dann bekämpfen sie dich und dann gewinnst du. (Mahatma Gandhi)
spawn89
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 82
Erhaltene Danke: 7

Linux
CodeTyphon
BeitragVerfasst: 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. :roll:
alzaimar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2889
Erhaltene Danke: 13

W2000, XP
D6E, BDS2006A, DevExpress
BeitragVerfasst: Fr 23.07.10 08:22 
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
... 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? :gruebel:

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
...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".

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
Sowas mache ich persönlich immer mit einer While-Schleife:...
Wieso einfach, wenns auch umständlich geht.

user profile iconNersgatt hat folgendes geschrieben Zum zitierten Posting springen:
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. :lol:

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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Fr 23.07.10 09:26 
Ich bin für diese Variante:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10183
Erhaltene Danke: 1256

W10ent
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Fr 23.07.10 09:33 
Moin!

user profile iconalzaimar hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
... 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? :gruebel:
Dämlich zusammengestellt, zugegeben. :nixweiss:

user profile iconalzaimar hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
...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".
Ja, selbstverständlich, danke für die Korrektur. :flehan:

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
spawn89
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 82
Erhaltene Danke: 7

Linux
CodeTyphon
BeitragVerfasst: Fr 23.07.10 09:36 
user profile iconthepaine91 hat folgendes geschrieben Zum zitierten Posting springen:
Ich bin für diese Variante:
ausblenden 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;


Da sieht man mal wieder, kaum kommen mehr unnötige Zeilen dazu sind Fehler drin.
thepaine91
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: Fr 23.07.10 09:39 
Das funktioniert hab es vorher getestet.
spawn89
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 82
Erhaltene Danke: 7

Linux
CodeTyphon
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 763
Erhaltene Danke: 27

Win XP, Windows 7, (Linux)
D6, D2010, C#, PHP, Java(Android), HTML/Js
BeitragVerfasst: 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.
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1747
Erhaltene Danke: 15

Win 7, *Ubuntu GNU/Linux*
*Anjuta* (C, C++, Python), Geany (Vala), Lazarus (Pascal), Eclipse (Java)
BeitragVerfasst: Fr 23.07.10 11:07 
was haltet ihr davon:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
for i := 1 to 20 do
  if i = 12 then
    asm
      dec  i
    end;