For Next Kinderkrankheiten?

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

For Next Kinderkrankheiten?

Beitrag 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
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag von Deeem2031 »

"Count ist übrigens als Count.c deklariert."

Das ist der Fehler.
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag 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
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag 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
Benutzeravatar
Deeem2031
Beiträge: 1232
Registriert: 29.08.2004 00:16
Wohnort: Vorm Computer
Kontaktdaten:

Beitrag 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.
Bild
[url=irc://irc.freenode.org/##purebasic.de]irc://irc.freenode.org/##purebasic.de[/url]
Benutzeravatar
Kurzer
Beiträge: 1617
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Beitrag 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 ;) )
ullmann
Beiträge: 205
Registriert: 28.10.2005 07:21

Beitrag 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
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Beitrag 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.
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Antworten