Seite 1 von 2

For Next Kinderkrankheiten?

Verfasst: 29.05.2006 19:24
von Kurzer
Ich weiß... ich klinge wie ein Meckerfuzzi... noch dazu wie einer, der
schon bei seinem ersten PB Projekt rummosert ;) (ist aber alles konstruktiv gemeint!)

Ich habe schon wieder eine Ungereimtheit gefunden, die ich mir nicht
erklären kann (außer, es ist ein Fehler in PB).

Und zwar geht es um For Next Schleifen die abwärts zählen sollen.

Code: Alles auswählen

For Count = 4 To 0
    Debug Count
Next Count
Das geht z.B. gar nicht rsp. er führt die Schleife gar nicht aus.
Ich hätte hier zumindest einen Dafaultstep von -1 erwartet.

Code: Alles auswählen

For Count = 4 To 0 Step -1
    Debug Count
Next Count
Wenn man den Step angibt, dann führt er die Schleife zwar aus, aber
er macht nach Null einfach weiter mit 255, 254, 253... usw.
Count ist übrigens als Count.c deklariert.

Das kann doch kein feature sein, oder?

In einer 4.00 Version sollten solche rudimentären Dinge, wie eine For-Schleife doch längst funktionieren?

Bitte nicht falsch verstehen - ich finde PB echt klasse und es hat mich erstmalig
dazu gebracht privat auf dem PC zu programmieren (komme vom Amiga - long time ago *rostabschüttel*),
aber solche Kleinigkeiten machen mich echt stutzig was die Ausgereiftheit
von PB angeht.

Ist das ein Fehler oder hat es mehr aufsich mit dem negativen For Next-Loop?

Gruß Markus

Verfasst: 29.05.2006 19:27
von Deeem2031
"Count ist übrigens als Count.c deklariert."

Das ist der Fehler.

Verfasst: 29.05.2006 19:36
von Kaeru Gaman
ein defaultstep von -1 ist absichtlich nicht drin.
du könntest ja auch schleifen-anfang und -ende als variablen übergeben,
und negative differenz nutzen um eben den schleifeninhalt nicht mehrfach zu bearbeiten.

wieauchimmer, ein default von immer +1 ist eigentlich so üblich, so kenn ich das in jedem BASIC dialekt seit über zwei jahrzehnten.

das verhalten von for/next mit byte resp. char ist schon etwas sonderbar, aber hat bestimmt seine gründe in dem ASM-code der erzeugt wird (nicht dass es kein compiler-fehler wäre).

es ist wohl einfach deshalb keinem aufgefallen, weil das verwenden von byte/char schleifenzählern absolut unüblich ist.

ich persönlich verwende n und t, evtl noch i für normale geschachtelte schleifen. x und y wenn ich geschachtelte koordinatenschleifen hab.
warum soll ich irgendwo n als byte definieren, wenn ich zehn zeilen später bis 300 zählen muss?
mein n ist immer long, und gut ist.

das soll nicht heißen, dass es kein bug wäre, es ist wohl nur so, dass es noch keinem aufgefallen ist. bestimmt gibt es ne codeseitige begründung, wo der 'denkfehler' des compilers liegt.
möglicherweise wird der stopwert per register verglichen, und word-null oder long-null ist nicht gleich byte-null... irgendsowas...
müsste man sich halt mal den erzeugten ASM-code anschaun, ums nachvollziehen zu können.

Verfasst: 29.05.2006 19:40
von Kurzer
"Count ist übrigens als Count.c deklariert."
Das ist der Fehler.
Hm, dann wäre ein Hinweis in der Hilfe vielleicht nicht schlecht, daß For Next nur mit Variablen der Größe Word oder größer funktioniert.

Im Übrigens funktioniert

Code: Alles auswählen

For Count = 4 to 0
  Debug Count
Next Count
...auch nicht, wenn Count ein Word ist. :(

Gruß Markus

Verfasst: 29.05.2006 19:42
von Kaeru Gaman
Kurzer hat geschrieben:Im Übrigen funktioniert
[...]
...auch nicht, wenn Count ein Word ist.
natürlich nicht. wie gesagt, default-step ist +1 und nur +1

Verfasst: 29.05.2006 19:48
von Kurzer
Kaeru Gaman hat geschrieben:...das verhalten von for/next mit byte resp. char ist schon etwas sonderbar, aber hat bestimmt seine gründe in dem ASM-code der erzeugt wird (nicht dass es kein compiler-fehler wäre).

es ist wohl einfach deshalb keinem aufgefallen, weil das verwenden von byte/char schleifenzählern absolut unüblich ist.
Vermutlich wird das so sein. Es auch richtig, daß es praktisch keine Einbußen bringt, wenn man einfach long nimmt, aber ich bin manchmal ziemlich "krümelkackerig", so daß ich dem Programm da halt einfach nur nen Byte gönnen wollte.

Wenn man's weiß isses ja gut.
Sollte aber viellieicht auch ein kurzer Hinweis in die Hilfe diesbezüglich.
Man sieht ja, kaum kommt nen Neuling, der es besonders gut machen will, schon stolpert er über Sachen, die die alten PB-Hasen gar nicht mehr sehen. :)

Gruß Markus

Verfasst: 29.05.2006 20:49
von Deeem2031
Kurzer hat geschrieben:Es auch richtig, daß es praktisch keine Einbußen bringt, wenn man einfach long nimmt, aber ich bin manchmal ziemlich "krümelkackerig", so daß ich dem Programm da halt einfach nur nen Byte gönnen wollte.
Da die meisten von uns ein 32-bit System haben ist es eher umgekehrt. (Mal von den drei Bytes im Speicher abgesehen (welche vielleicht trotzdem wegen Speedoptimierung draufgehen)) Und zwar arbeitet ein 32-bit System mit longs schneller als mit Bytes, von daher ist es völlig sinnlos Variablen als Byte, Char oder Word zu definieren, wenn es nicht wirklich notwendig ist.

Verfasst: 29.05.2006 22:51
von Kurzer
Deeem2031 hat geschrieben:Da die meisten von uns ein 32-bit System haben ist es eher umgekehrt. (Mal von den drei Bytes im Speicher abgesehen (welche vielleicht trotzdem wegen Speedoptimierung draufgehen)) Und zwar arbeitet ein 32-bit System mit longs schneller als mit Bytes, von daher ist es völlig sinnlos Variablen als Byte, Char oder Word zu definieren, wenn es nicht wirklich notwendig ist.
Oh, von der Seite habe ich das in der Tat noch nicht gesehen. :oops:
Danke für den Denkanstoß! :allright:

Gruß Markus (der sich mal langsam gedanklich von 8- und 16-Bit Systemen lösen sollte ;) )

Verfasst: 29.05.2006 23:36
von ullmann
Ich glaube, einen ähnlichen Thread gabs hier schon mal.

Auf den ersten Blick hätte ich Kurzer zugestimmt:
Char umfasst die Werte von 0 bis 255 und

Code: Alles auswählen

For count.c=4 To 0 Step -1
    Debug Count
Next
sollte also die Zeichencodes bzw. Zählwerte 4 bis 0 durchlaufen und dann stoppen.

Es gibt aber eine ganz logische Erklärung: Die Schleife wird verlassen, wenn der Zähler größer (bei positivem Step) bzw. kleiner (bei negativem Step) als der Endwert ist. Deshalb ist der Zähler nach dem Verlassen einer For-Next-Schleife immer um einen Step weiter als der Endwert.

Im obigen Beispiel kann aber Count nicht kleiner als 0 werden, im Bereich Char ergibt 0-1 gleich 255 und das ist größer als 0 und deshalb wird die Schleife nie verlassen.

Hier der Beweis:

Code: Alles auswählen

For Count.c=10 To 7 Step -1
    Debug Count
Next
Debug Count

Code: Alles auswählen

Count.c=0
Debug Count
Count-1
Debug Count
Rainer

Verfasst: 30.05.2006 09:30
von Kaeru Gaman
> wenn der Zähler größer (bei positivem Step) bzw. kleiner (bei negativem Step) als der Endwert ist.

TADAA!

siehste woll! war mir doch klar, dass es ne logische erklärung geben muss.
hab nur nich dran gedacht, dass die endbedingung größer bzw. kleiner ist,
und nicht gleich, obwohl das eigentlich logisch ist.