Autor |
Beitrag |
maxet
Hält's aus hier
Beiträge: 14
|
Verfasst: So 20.01.13 17:34
Hallo Leute,
ich habe mit einer ganz simplen for-Schleife ein Problem, das mich verwirrt.
Quelltext:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure allesnachruecken; var i,j,anzahl_nichtaktiv:integer; begin for i:=0 to 8 do begin anzahl_nichtaktiv:=0; for j:=1 to 30 do begin if not stockwerkwartende[i,j].aktiv then inc(anzahl_nichtaktiv); end; while anzahl_nichtaktiv>0 do begin if not (stockwerkwartende[i,j].aktiv) and (j<30) then stockwerkwartende[i,j]:=stockwerkwartende[i,j+1]; dec(anzahl_nichtaktiv); end; end; end; |
Das Problem habe ich bereits mit einem Haltepunkt und Strg+F7 (Ausdruck auswerten) gefunden: die for-Schleife lässt j über 30 hinaus gehen und beim Zugriff auf den Array stockwerkwartende:
Delphi-Quelltext 1:
| stockwerkwartende:array[0..8,1..30] of leute |
schmiert das Programm natürlich mit einem ERangeError ab.
Bis jetzt habe ich den Fehler nicht gefunden und ich bin ratlos
Habt ihr eine Idee?
Vielen Dank im Voraus
maxet
|
|
Mathematiker
      
Beiträge: 2622
Erhaltene Danke: 1447
Win 7, 8.1, 10
Delphi 5, 7, 10.1
|
Verfasst: So 20.01.13 18:07
Hallo,
die Zählschleife wird verlassen, wenn die Zählvariable die Grenze überschreitet. D.h. j wird erhöht und wenn es größer als 30, d.h. also 31, ist, wird die Schleife verlassen.
Zitat: | Hence the for...to statement is almost, but not quite, equivalent to this while construction:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| begin counter := initialValue; while counter <= finalValue do begin statement; counter := Succ(counter); end; end | |
Vorsicht aber! Bei eingeschalteter Optimierung kann j auch nach der Schleife unbestimmt sein.
Zitat: | After the for statement terminates, the value of counter is undefined. |
Die Zitate sind aus der Delphi-Hilfe.
Aus diesem Grund würde ich die Zählschleife durch eine repeat-until oder while-do-Schleife ersetzen.
Beste Grüße
Mathematiker
_________________ Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Für diesen Beitrag haben gedankt: maxet
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 20.01.13 18:29
Eigentlich sollte auch eine entsprechende Compilerwarnung kommen.  Zitat: | [DCC Warnung] UnitXXX.pas(xx): W1037 FOR-Schleifenvariable 'j' kann nach Durchlauf undefiniert sein |
Für diesen Beitrag haben gedankt: maxet
|
|
Tranx
      
Beiträge: 648
Erhaltene Danke: 85
WIN 2000, WIN XP
D5 Prof
|
Verfasst: So 20.01.13 20:38
maxet hat folgendes geschrieben : | Hallo Leute,
ich habe mit einer ganz simplen for-Schleife ein Problem, das mich verwirrt.
Quelltext:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| procedure allesnachruecken; var i,j,anzahl_nichtaktiv:integer; begin for i:=0 to 8 do begin anzahl_nichtaktiv:=0; for j:=1 to 30 do begin if not stockwerkwartende[i,j].aktiv then inc(anzahl_nichtaktiv); end; while anzahl_nichtaktiv>0 do begin if not (stockwerkwartende[i,j].aktiv) and (j<30) then stockwerkwartende[i,j]:=stockwerkwartende[i,j+1]; dec(anzahl_nichtaktiv); end; end; end; |
Das Problem habe ich bereits mit einem Haltepunkt und Strg+F7 (Ausdruck auswerten) gefunden: die for-Schleife lässt j über 30 hinaus gehen und beim Zugriff auf den Array stockwerkwartende:
Delphi-Quelltext 1:
| stockwerkwartende:array[0..8,1..30] of leute |
schmiert das Programm natürlich mit einem ERangeError ab.
Bis jetzt habe ich den Fehler nicht gefunden und ich bin ratlos
Habt ihr eine Idee?
Vielen Dank im Voraus
maxet |
Nach dem Verlassen ist die Schleifenvariable j nicht definiert. Das meckert eigentlich der Compiler an. Er kann auch 31 sein. Und damit würdest Du in der unterlegten Zeile schon den Grenzwert überschreiten
vieleicht schreibst Du besser:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| if (j>=1) and (j<30) then begin while anzahl_nichtaktiv>0 do begin if not (stockwerkwartende[i,j].aktiv) then stockwerkwartende[i,j]:=stockwerkwartende[i,j+1]; dec(anzahl_nichtaktiv); end; end; |
Dann kann die Schleife nie über j/j+1 > 30 gehen!
_________________ Toleranz ist eine Grundvoraussetzung für das Leben.
Für diesen Beitrag haben gedankt: maxet
|
|
maxet 
Hält's aus hier
Beiträge: 14
|
Verfasst: Mo 21.01.13 18:21
Danke!
So dumme Fehler übersehe ich also, wenn ich stundenlang vorm Bildschirm hocke ...
Aber komisch, der Compiler beachtet das gar nicht!? Naja.
Jetzt funktioniert es wieder 
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 21.01.13 21:51
|
|
|