Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - For schleifen Variable Definition


Caesar44 - Di 02.06.09 20:10
Titel: For schleifen Variable Definition
Guten Abend, nachdem gerade ebend mein anderes Problem großartig gelöst wurde habe ich folgendes Problem

In einer For-Schleife die wie folgt lautet


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
For i := 40 to 45 do
begin
....
....
..
end;

dachte ich heißt i wird als 40 definiert und startet mit diesem Wert die Schleife
Im nächsten Schleifendurchgang müsste dann i doch 41 sein oder???
Bei mir wird i aus unerfindlichen Gründen nähmlich im zweiten durchlauf 1, obwohl ich es nicht nochmal definiert habe.

Grüße


Marc. - Di 02.06.09 20:14

Sollte auch so sein. :) Zeig doch mal, was in der For-Schleife passiert. Wie hast du denn die Werte von i überprüft?


Xentar - Di 02.06.09 20:15

Hm ne, 1 kann eigentlich nicht vorkommen.
Was passiert denn in der Schleife? Kann es sein, dass du i da veränderst (sollte eigentlich ne Compiler Warnung erzeugen..)


Narses - Di 02.06.09 20:21

Moin!

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Hm ne, 1 kann eigentlich nicht vorkommen.
Doch, der Compiler "optimiert" die Laufvariable, wenn in der Schleife nicht darauf zugegriffen wird. :idea: ;)

cu
Narses


Caesar44 - Di 02.06.09 20:30

Hier passierts:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
      For p := 1 to 10 do
      begin
        If i-p*8 < 0 then
        break;
        Feld[i-8*p] :=1;
      end;
      Feld[i]:=2;  // Wichtig


Sobald Feld[i]:= 2 dran kommt wird i =1
Ist das diese "optimierung"?
Und ja es kommt eine Warnung: For-Schleifenvariable muss einfache Lokalvariable sein.
Muss ich i also lokal definieren?


Martok - Di 02.06.09 20:33

user profile iconCaesar44 hat folgendes geschrieben:
Und ja es kommt eine Warnung: For-Schleifenvariable muss einfache Lokalvariable sein.
Muss ich i also lokal definieren?

Ja, steht da ja ;)

Theoretisch müsste da auch noch eine 2. Warnung kommen, denn nach der Schleife ist i undefiniert. Genau das müsste er dir eigentlich auch noch sagen?


Marc. - Di 02.06.09 20:34

user profile iconMartok hat folgendes geschrieben Zum zitierten Posting springen:
Theoretisch müsste da auch noch eine 2. Warnung kommen, denn nach der Schleife ist i undefiniert. Genau das müsste er dir eigentlich auch noch sagen?

Warum denn in diesem Beispiel nach der For-Schleife und nicht schon vorher? :gruebel:

Achso, du vermutest, dass die Schleifen in jeweils seperaten Prozeduren ausgeführt werden?


Xentar - Di 02.06.09 20:42

user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Doch, der Compiler "optimiert" die Laufvariable, wenn in der Schleife nicht darauf zugegriffen wird. :idea: ;)

Ach man.. ;)
Wenn man eine Schleife schon genau von 40 bis 45 laufen lässt, geh ich mal davon aus, dass das schon nen Sinn hat -> Man diese Variable benutzt :D


Martok - Di 02.06.09 20:45

Ich hab jetzt einfach mal unmittelbar auf den Code geantwortet, da der erste da irgendwie keinen Zusammenhang mit hat ;)

:shock: ach, das ist ja ne andere Variable? Wo kommt denn die jetzt her?
Okay, ich erkläre offiziell dass ich nicht weiß, in welcher Reihenfolge der Code jetzt aufgerufen wird ;)


user profile iconMarc. hat folgendes geschrieben Zum zitierten Posting springen:
Warum denn in diesem Beispiel nach der For-Schleife und nicht schon vorher? :gruebel:

Vorher auch, klar.

Mit undefiniert meinte ich, dass man sich nicht darauf verlassen kann, dass die schleife Variable auch wirklich in der Richtung durchläuft. Der Compiler wird immer versuchen, auf 0 zu zählen, dazu werden ggf. noch interne Variablen benutzt. Oder auch nicht, wie Narses schon gesagt hat.

Wird unter anderem hier [http://web.archive.org/web/20021021094615/www.optimalcode.com/general.htm] beschrieben, wo genau, müsste ich auch erst suchen ;)


Caesar44 - Di 02.06.09 20:59

Hallo ihr seid klasse, Problem hat sich in Wohlgefallen aufgelöst, also kommt das nächste:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
For p := 1 to 10 do  // i=28
        begin
          If (i+p*7 > 64and (i+p*7<>1and (i+p*7<>9and (i+p*7<>17and (i+p*7<>25and (i+p*7<>33and (i+p*7<>41and (i+p*7<>49and (i+p*7<>57then
          break;
          Feld[i+p*7]:=1;
        end;


Ich habe unter anderem definiert das die Schleife enden soll,wenn i+p*7 = 49 ist.
Das müsste doch eigentlich bei p=3 eintreten oder?
28 plus 21 = 49.
Aber das Programm scheint das zu ignorieren. Villeicht mag es mich nicht mehr :-D

Gruß Caesar


Marc. - Di 02.06.09 21:08


Delphi-Quelltext
1:
If (i+p*7 > 64and (i+p*7<>1and (i+p*7<>9and (i+p*7<>17and (i+p*7<>25and (i+p*7<>33and (i+p*7<>41and (i+p*7<>49and (i+p*7<>57then                    

user profile iconCaesar44 hat folgendes geschrieben Zum zitierten Posting springen:
Ich habe unter anderem definiert das die Schleife enden soll,wenn i+p*7 = 49 ist.

Das hast du nicht. Und selbst wenn du auf = 49 prüfst, ist zwar eine Abbruch-Bedingung von vielen erfüllt, aber nun mal nicht ALLE! Was hast du mir diesem merkwürdigen Konstrukt eigentlich vor? :gruebel:


koegi - Di 02.06.09 21:20

user profile iconCaesar44 hat folgendes geschrieben Zum zitierten Posting springen:
Hallo ihr seid klasse, Problem hat sich in Wohlgefallen aufgelöst, also kommt das nächste:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
For p := 1 to 10 do  // i=28
        begin
          If (i+p*7 > 64and (i+p*7<>1and (i+p*7<>9and (i+p*7<>17and (i+p*7<>25and (i+p*7<>33and (i+p*7<>41and (i+p*7<>49and (i+p*7<>57then
          break;
          Feld[i+p*7]:=1;
        end;


Ich habe unter anderem definiert das die Schleife enden soll,wenn i+p*7 = 49 ist.
Das müsste doch eigentlich bei p=3 eintreten oder?
28 plus 21 = 49.
Aber das Programm scheint das zu ignorieren. Villeicht mag es mich nicht mehr :-D

Gruß Caesar



Hallo, Caesar!

Oben steht if (i+p*7 > 64and ...
Kann es sein, dass Du dich bei der ersten Bedingung vertan hast? (if (i+p*7 <> 64) ...
Wenn ein Wert größer 64 ist, dann ist eine Prüfung auf Werte, die kleiner als 64 sind, sinnlos.

Den sinn des obigen Codes begreife ich leider auch nicht ganz...

Viele Grüße

Thomas


Caesar44 - Di 02.06.09 21:31

Tut mir leid, der Code ist tatsächlich nicht ganz verständlich, wenn man das Programm nicht kennt.
es ist das acht Damen Problem. dabei müssen um die Dame bestimmte der 64 Felder besetzt werden. Die reihe also jedes +-feld8, die Spalte und noch die schrägen Felder. dabei rechne ich +7 felder in dem Fall des Quelltextes um die Felder nach schräg oben als besetzt zu markieren. Allerding soll die Schleife stoppen, wenn ein feld am obersten Rand bestzt wurde, weil die Schleife Sonst in der nächsten Spalte wieder von unten anfängt, was ja nicht sinn der sache ist.
Ich hoffe ich konnte es einigermaßen verständlich machen. Ich könnte statt "and" "or" nehmen oder?

So jetzt hab ich es richtig gemacht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
        For p := 1 to 10 do
        begin
          If (i+p*7 > 64or (i+p*7=1or (i+p*7=9or (i+p*7=17or (i+p*7=25or (i+p*7=33or (i+p*7=41or (i+p*7=49or (i+p*7=57then
          begin
            Feld[i+p*7]:=1;
            break;
          end;


Jetzt werden alle Felder schräg oberhalb der Dame bis an die Kante besetzt
Grüße


koegi - Di 02.06.09 21:44

user profile iconCaesar44 hat folgendes geschrieben Zum zitierten Posting springen:
Tut mir leid, der Code ist tatsächlich nicht ganz verständlich, wenn man das Programm nicht kennt.
es ist das acht Damen Problem. dabei müssen um die Dame bestimmte der 64 Felder besetzt werden. Die reihe also jedes +-feld8, die Spalte und noch die schrägen Felder. dabei rechne ich +7 felder in dem Fall des Quelltextes um die Felder nach schräg oben als besetzt zu markieren. Allerding soll die Schleife stoppen, wenn ein feld am obersten Rand bestzt wurde, weil die Schleife Sonst in der nächsten Spalte wieder von unten anfängt, was ja nicht sinn der sache ist.
Ich hoffe ich konnte es einigermaßen verständlich machen. Ich könnte statt "and" "or" nehmen oder?

So jetzt hab ich es richtig gemacht:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
        For p := 1 to 10 do
        begin
          If (i+p*7 > 64or (i+p*7=1or (i+p*7=9or (i+p*7=17or (i+p*7=25or (i+p*7=33or (i+p*7=41or (i+p*7=49or (i+p*7=57then
          begin
            Feld[i+p*7]:=1;
            break;
          end;


Jetzt werden alle Felder schräg oberhalb der Dame bis an die Kante besetzt
Grüße


Ei, sieh mal einer guck!

Plötzlich präsentierst Du uns hier eine or-Abfrage statt einer and-Abfrage!
So macht das ganze schon mehr Sinn...

Viele Grüße

Thomas


jaenicke - Di 02.06.09 22:57

user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconNarses hat folgendes geschrieben Zum zitierten Posting springen:
Doch, der Compiler "optimiert" die Laufvariable, wenn in der Schleife nicht darauf zugegriffen wird. :idea: ;)

Ach man.. ;)
Wenn man eine Schleife schon genau von 40 bis 45 laufen lässt, geh ich mal davon aus, dass das schon nen Sinn hat -> Man diese Variable benutzt :D
Das heißt aber nicht, dass die Schleife intern so läuft. Intern kann die trotzdem von 4 auf 0 laufen z.B., denn der Compiler sorgt dafür, dass trotzdem die richtigen Werte verwendet werden.

Beim Debuggen werden aber die Werte 4 bis 0 z.B. angezeigt, weil die IDE von Delphi keine Ahnung hat, dass das so optimiert wurde. Und deshalb sieht das beim Debuggen falsch aus. Aber auch nur da. Benutzt werden die richtigen Werte. Die stehen aber woanders als es die IDE erwartet.

Fazit: Zum Debuggen insbesondere bei solchen Start- und Endwerten für Schleifen generell die Optimierung beim Kompilieren deaktivieren...