Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - For schleifen
Flamefire - Di 04.08.09 22:19
Titel: For schleifen
mal eine allgemeine Frage zu einer for-schleife
ich hab an diversen stellen gelesen eine schleife wie:
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 - Di 04.08.09 22:22
Also, ich kenn das nur so: Wenn der Endwert kleiner ist, als der Startwert, wird die Schleife übersprungen.
Narses - Di 04.08.09 22:26
Moin!
Flamefire hat folgendes geschrieben : |
ich hab an diversen stellen gelesen eine schleife wie:
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
Tilman - 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 ^^
HelgeLange - Di 04.08.09 23:02
Xentar hat folgendes geschrieben : |
| Also, ich kenn das nur so: Wenn der Endwert kleiner ist, als der Startwert, wird die Schleife übersprungen. |
das wäre mir neu. :shock:
Xentar - Di 04.08.09 23:18
Hng, mkay, habs grad ausprobiert.
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.
je nach Compilereinstellung gibt es einen Integerüberlauf, oder die Schleife wird ausgeführt.
Delphi-Quelltext
1:
| var i: integer; a: cardinal; |
Je nach Compilereinstellung: Integerüberlauf, oder Schleife wird NICHT ausgeführt.
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.
Muck - 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 - 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.
Flamefire - Mi 05.08.09 10:28
ok also zusammenfassung:
1) laufvariable zwingend ein signed typ, dann keine probleme
2) downto schleife ist schneller
Danke
Delete - Mi 05.08.09 10:36
Wenn möglich optimiert der Compiler automatisch for-Schleifen dahingehend, dass sie intern rückwärtlaufe.
Flamefire - 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.
Tilman - Mi 05.08.09 14:02
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.
der organist - Mi 05.08.09 18:44
kann das denn nicht manchmal Probleme geben?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| var ar:Array[0..4] of 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?
Flamefire - 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 - Mi 05.08.09 20:23
hätte mich schon gewundert, denn sonst hätte die Hälfte meiner (funktionierenden) Programme nicht mehr funktioniert...
HelgeLange - 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..
Flamefire - 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:
Delphi-Quelltext
1: 2: 3:
| INC ESI CMP ESI,4 JB x |
2) Schleife bis 0
einfach 1 befehl weniger...
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!