Autor Beitrag
Flamefire
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Di 04.08.09 22:19 
mal eine allgemeine Frage zu einer for-schleife
ich hab an diversen stellen gelesen eine schleife wie:
ausblenden Delphi-Quelltext
1:
for i:=0 to a-1 do...					

sei gefährlich, da wenn a=0 ist seltsames zeug rauskommt oder ewig lange falsche schleifenabläufe
darum kurz als frage: ist sicher, dass der die bedingung vor der schleife prüft (also 0<=a-1) oder muss ich wirklich vor jede schleife ne if abfrage setzen?
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Di 04.08.09 22:22 
Also, ich kenn das nur so: Wenn der Endwert kleiner ist, als der Startwert, wird die Schleife übersprungen.

_________________
PROGRAMMER: A device for converting coffee into software.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 04.08.09 22:26 
Moin!

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
ich hab an diversen stellen gelesen eine schleife wie:
ausblenden Delphi-Quelltext
1:
for i:=0 to a-1 do...					

sei gefährlich, da wenn a=0 ist seltsames zeug rauskommt oder ewig lange falsche schleifenabläufe
darum kurz als frage: ist sicher, dass der die bedingung vor der schleife prüft (also 0<=a-1) oder muss ich wirklich vor jede schleife ne if abfrage setzen?
Wie kommst du denn da drauf? :shock: Und die Quellen würde ich gerne mal sehen. :? Ich halte das für Aberglauben 8) wenn das tatsächlich so wäre, würden ziemlich viele meiner Programme ziemlich häufig gar nicht laufen... :lol:

Schau dir doch einfach mal den Assembler-Code an, den der Compiler erzeugt, bist doch ein Bitfummler. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Tilman
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1405
Erhaltene Danke: 51

Win 7, Android
Turbo Delphi, Eclipse
BeitragVerfasst: Di 04.08.09 22:36 
Vielleicht wenn a = byte oder cardinal oder so ist?
//edit
habs getestet: wenn i cardinal ist, wird die Schleife maximal durchlaufen. Naja aber wer macht sowas schon ^^

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: Di 04.08.09 23:02 
user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Also, ich kenn das nur so: Wenn der Endwert kleiner ist, als der Startwert, wird die Schleife übersprungen.

das wäre mir neu. :shock:

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Di 04.08.09 23:18 
Hng, mkay, habs grad ausprobiert.
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
var i, a: integer;
begin
  A := 0;
  for I := 0 to a - 1 do
    ShowMessage(IntToStr(i));
end;

Schleife wird nicht durchlaufen.


ausblenden Delphi-Quelltext
1:
var i, a: cardinal;					

je nach Compilereinstellung gibt es einen Integerüberlauf, oder die Schleife wird ausgeführt.

ausblenden Delphi-Quelltext
1:
var i: integer; a: cardinal;					

Je nach Compilereinstellung: Integerüberlauf, oder Schleife wird NICHT ausgeführt.

ausblenden Delphi-Quelltext
1:
var  i: cardinal; a: integer;					

Fehler bei Bereichsprüfung / Schleife wird durchlaufen

Da ich selber in den meisten Fällen i: integer verwende, hatte ich bisher keine Probleme, da die Schleife nicht ausgeführt wird.
Warum das so ist, können euch sicher die ASM Profis erklären. :D
Das ganze hab ich übrigens sowie mit, als auch ohne Optimierung getestet - also sollte es daran auch nicht liegen.

_________________
PROGRAMMER: A device for converting coffee into software.
Muck
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 98
Erhaltene Danke: 8

Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
BeitragVerfasst: Di 04.08.09 23:46 
Hallo zusammen,

der Grund warum mal die Schleife durchlaufen wird und mal nicht liegt ganz einfach nur am Variablen Typ.

Bei Signed Typen wie ShortInt,SmallInt,Integer,LongInt,Int64 wird die Schleife nicht durchlaufen, da der Wert -1 ist, und damit kleiner als der Startwert.

Bei Unsigned Typen wie Byte,Word,Longword,UInt64,Cardinal wird die Schleife durchlaufen, falls der Integerueberlauf oder Bereichsfehler ignoriert wird. Da z.B. bei Cardinal (32 BIT Unsigned)
$00000000-$00000001 = $FFFFFFFF. Wird dieser Ueberlauf dann ignoriert werden $FFFFFFFF durchlaeufe gemacht.

also von 0 bis 4294967295. Viel Spass beim warten. :-)

Markus

(Editiert, da ich nicht mehr so oft Deutsch schreibe, sorry ;-) )
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Mi 05.08.09 08:45 
Das mit der Schleifenprüfung war einmal in ganz alten Delphi-Versionen. Da hat der Compiler das wirklich nicht von sich aus geporüft, was zu den genannten Effekten geführt hat. Mindestens seit Delphi 4 ist das aber behoben, IMHO aber auch bereits in D3.

Tipp am Rande: Nutze Schleifen wo immer möglich und sinnvoll mit Downto 0, da der Compiler dann eine schnellere Prüfung der Endbedingung ausführen kann.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 05.08.09 10:28 
ok also zusammenfassung:
1) laufvariable zwingend ein signed typ, dann keine probleme
2) downto schleife ist schneller

Danke
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 05.08.09 10:36 
Wenn möglich optimiert der Compiler automatisch for-Schleifen dahingehend, dass sie intern rückwärtlaufe.
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 05.08.09 10:45 
jop, habe ich gesehn.
und wenn man die zählvariable aber verwendet und gleich eine rückwärtslaufende schleife hat, spart das aufwand.
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Mi 05.08.09 13:36 
Tilman
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1405
Erhaltene Danke: 51

Win 7, Android
Turbo Delphi, Eclipse
BeitragVerfasst: Mi 05.08.09 14:02 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
www.michael-puff.de/...ifeRueckwaerts.shtml

Ah gut den Artikel wollte ich eh gerne mal lesen, hatte den neulich gesehn aber die Zuordnung auf deinem Server stimmt leider irgendwie nicht mehr bei alten Beiträgen.

_________________
Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
der organist
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 467
Erhaltene Danke: 17

WIN 7
NQC, Basic, Delphi 2010
BeitragVerfasst: Mi 05.08.09 18:44 
kann das denn nicht manchmal Probleme geben?

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
var 
  ar:Array[0..4of Integer;
  i,neuerWert:Integer;
begin
  for i:=0 to 3 do 
    ar[i]:=ar[i+1];
  ar[4]:=neuerWert;
end;


Wenn ich das hochzähle komme ich zu einem Array, in dem die letzten vier Werte nach vorne gerückt sind und der letzte Platz durch den neuen Wert eingenommen wird.

Wenn ich das aber herunterzähle, dann hab ich überall, bis auf ar[4] den wert von ar[3] stehen. In ar[4] steht dann der neue Wert.

Gibts da ne Überprüfung und wenn ja, welche Kriterien werden da denn geprüft?

_________________
»Gedanken sind mächtiger als Waffen. Wir erlauben es unseren Bürgern nicht, Waffen zu führen - warum sollten wir es ihnen erlauben, selbständig zu denken?« Josef Stalin
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Mi 05.08.09 20:06 
die schleife läuft nicht wirklich rückwärts
nur die zählvariable läuft rückwärts
intern wird da mit pointer gearbeitet, die hochzählen.
der organist
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 467
Erhaltene Danke: 17

WIN 7
NQC, Basic, Delphi 2010
BeitragVerfasst: Mi 05.08.09 20:23 
hätte mich schon gewundert, denn sonst hätte die Hälfte meiner (funktionierenden) Programme nicht mehr funktioniert...

_________________
»Gedanken sind mächtiger als Waffen. Wir erlauben es unseren Bürgern nicht, Waffen zu führen - warum sollten wir es ihnen erlauben, selbständig zu denken?« Josef Stalin
HelgeLange
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 735
Erhaltene Danke: 6

Windows 7
Delphi7 - Delphi XE
BeitragVerfasst: Do 06.08.09 02:19 
Der grund ist, dass JNZ / JZ (Jump if not Zero / Jump if Zero) sind schneller als auf eine bestimmte Grösse testen von den Taktzyklen her..

_________________
"Ich bin bekannt für meine Ironie. Aber auf den Gedanken, im Hafen von New York eine Freiheitsstatue zu errichten, wäre selbst ich nicht gekommen." - George Bernhard Shaw
Flamefire Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1207
Erhaltene Danke: 31

Win 10
Delphi 2009 Pro, C++ (Visual Studio)
BeitragVerfasst: Do 06.08.09 09:59 
Jein...
bei einer Schleife, die bis 0 läuft muss einfach nicht verglichen werden, weil das vergleichsergebnis bereits beim berechnen anfällt

Bsp:
1) Schleife bis 4:
ausblenden Delphi-Quelltext
1:
2:
3:
INC ESI
CMP ESI,4
JB x

2) Schleife bis 0
ausblenden Delphi-Quelltext
1:
2:
DEC ESI
JNZ x


einfach 1 befehl weniger...