Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi For-To-Do-Schleife beginnt nicht mit Startwert (https://www.delphipraxis.net/182498-do-schleife-beginnt-nicht-mit-startwert.html)

DevidEspenschied 29. Okt 2014 13:10

Delphi-Version: XE

For-To-Do-Schleife beginnt nicht mit Startwert
 
Ich habe im Programm eine einfache For-To-Do-Schleife, und verwende als Bis-Zähler eine Byte-Variable:

Delphi-Quellcode:
var i, MaxZahl : Byte;
begin
  MaxZahl:=20;
  for i:=1 to MaxZahl do
  begin
    {}
  end;
end;
Nun habe ich das Phänomen, dass bereits der erste Durchlauf für die Schleife den Wert 20 in der Zählervariable i liefert, anstatt 1. Woran kann das liegen?

Uwe Raabe 29. Okt 2014 13:15

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Zitat:

Zitat von devidespe (Beitrag 1277847)
Nun habe ich das Phänomen, dass bereits der erste Durchlauf für die Schleife den Wert 20 in der Zählervariable i liefert, anstatt 1.

Wie stellst du das denn fest?

DevidEspenschied 29. Okt 2014 13:18

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Na indem ich bei der ersten Zeile zwischen begin-end einen Breakpoint setzen und mir im Debugger den Wert anschaue.

WM_CLOSE 29. Okt 2014 13:18

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Die Optimierung lässt die Schleife falsch herum laufen, weil das Vergleichen mit 0 (die Abbruchbedingung der Schleife) etwas schneller ist als mit 20.
Das ist so als würdest du eine For-Downto-Do Schleife bauen.
siehe: http://www.delphi-treff.de/object-pascal/schleifen/

DevidEspenschied 29. Okt 2014 13:20

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Ich habe nun alles auf Repeat-Until geändert und die 20 als Abbruchbedingung genommen. Funktioniert.

Sherlock 29. Okt 2014 13:33

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
War denn das Ergebnis nach Durchlauf der For-Schleife unerwartet?

Sherlock

Popov 29. Okt 2014 13:48

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Zitat:

Zitat von devidespe (Beitrag 1277851)
Na indem ich bei der ersten Zeile zwischen begin-end einen Breakpoint setzen und mir im Debugger den Wert anschaue.

Das ist dein "Problem" in Anführungszeichen ;)

Du nutzt i nicht in der Schleife, also ist es für den weiteren Programmablauf egal wie der Wert von i ist. Und weil es egal ist, sagt sich der Compiler, dass es für ihn optimaler ist mit dem höheren Wert zu beginnen und runter zu zählen.

Wie gesagt, diesen Effekt hast du nur, weil der Wert von i nicht benötigt wird. Es ist also egal ob For rauf oder runter zählt.

Anders sieht es aber aus wenn du den i-Wert benötigst. Dann wird so gezählt wie es soll. Du kannst es testen:
Delphi-Quellcode:
var i, MaxZahl : Byte;
begin
  MaxZahl:=20;
  for i:=1 to MaxZahl do
  begin
    ShowMessage(IntToStr(i));
  end;
end;
Lass es laufen. Du wirst sehen, es beginnt bei 1.

Also, dein Phänomen tritt nur dann auf wenn es egal ist. Ist es egal, macht der Compiler das was für ihn optimaler ist. Ist es nicht egal, wird es so gemacht wie du es willst.

Sherlock 29. Okt 2014 13:49

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Weshalb ich fragte, ob das Ergebnis nach der Schlafe denn wie erwartet ist...

Sherlock

himitsu 29. Okt 2014 14:19

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Zitat:

Zitat von Sherlock (Beitrag 1277860)
Weshalb ich fragte, ob das Ergebnis nach der Schlafe denn wie erwartet ist...

NEIN.

"Nach" der Schleife ist i immer "ungültig".


Intern kann der Compiler das i anders laufen lassen, je nach Code-Optimierung, aber bei "Verwendung" ist i immer richtig (wird intern wieder umgerechnet)
Der Debugger zeigt nur manchmal was Falsches an, vorallem wenn man i innerhalb der Schleife garnicht verwendet. :stupid:



Zitat:

Delphi-Quellcode:
MaxZahl:=20;
for i:=1 to MaxZahl do

Ach ja, Delphi cached den Endwert sowieso immer, weswegen man dort keine Variable benötigt.
Drum knallt es gern, wenn man Items aus Listen löscht und dabei die Schleife vorwärts durchläuft. :angel2:

Sherlock 29. Okt 2014 15:40

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Hat jemand nach dem i gefragt? oO

Das was die Schleife bezwecken sollte, wurde erreicht, ja oder nein? Das war die Frage an den TE. Falls nein hätten wir es ja mit einem Bug zu tun.

Sherlock

himitsu 29. Okt 2014 16:07

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Aso. :oops:

Dachte du meinst das i, weil da ganz oben, außer dem Kommentar ja nichts in der Schleife war, was ein Ergebnis liefern könnte.

Sir Rufo 29. Okt 2014 17:42

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Zitat:

Zitat von himitsu (Beitrag 1277903)
Aso. :oops:

Dachte du meinst das i, weil da ganz oben, außer dem Kommentar ja nichts in der Schleife war, was ein Ergebnis liefern könnte.

Jupp, das Ergebnis ist doch völlig korrekt 20x nix machen. Läuft wie erwartet :stupid:

Uwe Raabe 29. Okt 2014 17:46

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Zitat:

Zitat von Sir Rufo (Beitrag 1277950)
Zitat:

Zitat von himitsu (Beitrag 1277903)
Aso. :oops:

Dachte du meinst das i, weil da ganz oben, außer dem Kommentar ja nichts in der Schleife war, was ein Ergebnis liefern könnte.

Jupp, das Ergebnis ist doch völlig korrekt 20x nix machen. Läuft wie erwartet :stupid:

Bei aktiver Optimierung wird die Schleife sogar ganz weggelassen.

Sir Rufo 29. Okt 2014 17:50

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1277951)
Zitat:

Zitat von Sir Rufo (Beitrag 1277950)
Zitat:

Zitat von himitsu (Beitrag 1277903)
Aso. :oops:

Dachte du meinst das i, weil da ganz oben, außer dem Kommentar ja nichts in der Schleife war, was ein Ergebnis liefern könnte.

Jupp, das Ergebnis ist doch völlig korrekt 20x nix machen. Läuft wie erwartet :stupid:

Bei aktiver Optimierung wird die Schleife sogar ganz weggelassen.

Da 20x nix genauso gut wie gar nicht nix, ist das Ergebnis gleich - nur schneller :stupid:

DevidEspenschied 30. Okt 2014 20:17

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Hallo,

sorry für die verspätete Antwort.

Ich verwende i in meinem Programm tatsächlich in der Schleife, und habe ein Array mit 20 Einträgen, welches ich über die For-Zählervariable anspreche:

Delphi-Quellcode:
var i, MaxZahl : Byte;
    TestArray : Array[1..20] of string;
begin
   {Array-Befüllung}

   MaxZahl:=20;
   for i:=1 to MaxZahl do
   begin
     if TestArray[i] = '' then ShowMessage('Leerer Arrayeintrag');
   end;
end;
Aber wie gesagt, ich bin umgestiegen zu Repeat...Until und es läuft.

himitsu 30. Okt 2014 20:31

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Zitat:

Zitat von devidespe (Beitrag 1278108)
Aber wie gesagt, ich bin umgestiegen zu Repeat...Until und es läuft.

Warum?

Funktionieren tun alle 5 Arten von Schleifen, auch die For-To.

Was die Schleifen intern machen ist für die Funktion vollkommen unerheblich.

Uwe Raabe 30. Okt 2014 20:54

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Zitat:

Zitat von himitsu (Beitrag 1278109)
Zitat:

Zitat von devidespe (Beitrag 1278108)
Aber wie gesagt, ich bin umgestiegen zu Repeat...Until und es läuft.

Warum?

Funktionieren tun alle 5 Arten von Schleifen, auch die For-To.

Das wäre wirklich mal interessant zu wissen - ob die for-Schleife trotz falschen Werts im Debugger das richtige Ergebnis liefert. Vielleicht liegt das Problem eher in einem Debugger-Fehler?

p80286 30. Okt 2014 21:22

AW: For-To-Do-Schleife beginnt nicht mit Startwert
 
Zitat:

Zitat von himitsu (Beitrag 1278109)
Zitat:

Zitat von devidespe (Beitrag 1278108)
Aber wie gesagt, ich bin umgestiegen zu Repeat...Until und es läuft.

Warum?

Funktionieren tun alle 5 Arten von Schleifen, auch die For-To.

Was die Schleifen intern machen ist für die Funktion vollkommen unerheblich.

Naja vielleicht ist es doch so etwas:
Delphi-Quellcode:
for i:=0 to 20 do
  irgendwas_ohne_i
inc(i,1); {das geht wahrscheinlich in die Hose}
Gruß
K-H


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:53 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