Autor Beitrag
maxet
Hält's aus hier
Beiträge: 14



BeitragVerfasst: So 20.01.13 17:34 
Hallo Leute,

ich habe mit einer ganz simplen for-Schleife ein Problem, das mich verwirrt.

Quelltext:
ausblenden 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  //hier liegt das Problem!
    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<30then 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:
ausblenden Delphi-Quelltext
1:
stockwerkwartende:array[0..8,1..30of 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
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: 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:
ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 20.01.13 18:29 
Eigentlich sollte auch eine entsprechende Compilerwarnung kommen. :gruebel:
Zitat:
[DCC Warnung] UnitXXX.pas(xx): W1037 FOR-Schleifenvariable 'j' kann nach Durchlauf undefiniert sein

Für diesen Beitrag haben gedankt: maxet
Tranx
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 648
Erhaltene Danke: 85

WIN 2000, WIN XP
D5 Prof
BeitragVerfasst: So 20.01.13 20:38 
user profile iconmaxet hat folgendes geschrieben Zum zitierten Posting springen:
Hallo Leute,

ich habe mit einer ganz simplen for-Schleife ein Problem, das mich verwirrt.

Quelltext:
ausblenden 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  //hier liegt das Problem!
    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<30then 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:
ausblenden Delphi-Quelltext
1:
stockwerkwartende:array[0..8,1..30of 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:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
    if (j>=1and (j<30then
    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 Threadstarter
Hält's aus hier
Beiträge: 14



BeitragVerfasst: Mo 21.01.13 18:21 
Danke!

So dumme Fehler übersehe ich also, wenn ich stundenlang vorm Bildschirm hocke ... :autsch:
Aber komisch, der Compiler beachtet das gar nicht!? Naja.

Jetzt funktioniert es wieder :party:
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 21.01.13 21:51 
user profile iconmaxet hat folgendes geschrieben Zum zitierten Posting springen:
Aber komisch, der Compiler beachtet das gar nicht!? Naja.
Wie schon geschrieben, bei mir kommt da die Warnung. ;-)