| Autor |
Beitrag |
Flamefire
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: Di 04.08.09 22:19
mal eine allgemeine Frage zu einer for-schleife
ich hab an diversen stellen gelesen eine schleife wie:
Delphi-Quelltext
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
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: 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
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 04.08.09 22:26
Moin!
Flamefire hat folgendes geschrieben : | ich hab an diversen stellen gelesen eine schleife wie:
Delphi-Quelltext
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?  Und die Quellen würde ich gerne mal sehen.  Ich halte das für Aberglauben  wenn das tatsächlich so wäre, würden ziemlich viele meiner Programme ziemlich häufig gar nicht laufen...
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
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: 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
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: Di 04.08.09 23:02
_________________ "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
      
Beiträge: 2077
Erhaltene Danke: 2
Win XP
Delphi 5 Ent., Delphi 2007 Prof
|
Verfasst: 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.
Delphi-Quelltext
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.
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
      
Beiträge: 98
Erhaltene Danke: 8
Win 8, Win 7, Vista, Win XP
Delphi XE3, Delphi 2009, Delphi 2007, Delphi 5
|
Verfasst: 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
      
Beiträge: 8721
Erhaltene Danke: 191
Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
|
Verfasst: 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 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: 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
|
Verfasst: Mi 05.08.09 10:36
Wenn möglich optimiert der Compiler automatisch for-Schleifen dahingehend, dass sie intern rückwärtlaufe.
|
|
Flamefire 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: 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
|
Verfasst: Mi 05.08.09 13:36
|
|
Tilman
      
Beiträge: 1405
Erhaltene Danke: 51
Win 7, Android
Turbo Delphi, Eclipse
|
Verfasst: 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.
_________________ Bringe einen Menschen zum grübeln, dann kannst du heimlich seinen Reis essen.
(Koreanisches Sprichwort)
|
|
der organist
      
Beiträge: 467
Erhaltene Danke: 17
WIN 7
NQC, Basic, Delphi 2010
|
Verfasst: 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?
_________________ »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 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: 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
      
Beiträge: 467
Erhaltene Danke: 17
WIN 7
NQC, Basic, Delphi 2010
|
Verfasst: 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
      
Beiträge: 735
Erhaltene Danke: 6
Windows 7
Delphi7 - Delphi XE
|
Verfasst: 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 
      
Beiträge: 1207
Erhaltene Danke: 31
Win 10
Delphi 2009 Pro, C++ (Visual Studio)
|
Verfasst: 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
Delphi-Quelltext
einfach 1 befehl weniger...
|
|