Diskussion:NEXT

Aus C64-Wiki
Zur Navigation springenZur Suche springen

Sieht nun richtig gut aus, ebenfalls das Beispiel. Noch eine kurze Rückfrage, wird durch den Abbruch der J-Schleifen, eigentlich die anderem Schleifen "sauber" verlassen? Wenn nicht, sollte man darauf noch unter dem Beispiel kurz darauf hinweisen. --Jodigi 16:47, 12. Nov. 2009 (CET)

Wird sauber verlassen, weil bei einem NEXT Var am Stack genau der zu Var gehörende FOR-Block gesucht wird, der zu Var gehört. Dabei werden die übersprungengen FOR-NEXT-Blöck (aber nur die) verworfen - eher für Stackoperationen untypisch, aber gewährleistet die Konsistenz bzw. mehr Spielraum bei der Programmierung ohne den Programmierer zu strickt Zwänge gefangen zu halten. Ein echtes Feature von BASIC V2 - keine Ausnutzung eines implementierungstechnischen Details! (siehe auch ROM-Routine $A38A) --JohannKlasek 06:06, 13. Nov. 2009 (CET)
Hab ich mal so korrigiert (J auf Höchstwert beendet die Schleife ohne Rückstände). --GoDot 22:32, 12. Nov. 2009 (CET)
Das Beenden ohne Rückstände hat auch das ursprüngliche Beispiel gemacht. Das war ja der Witz bei dem Beispiel, dass aus der Schleife ohne Schleifenvariablen-Spielereien herausspringt und nebenbei der Stack konsistent bleibt. Mit geänderten Variante wird außerdem der Letztstand der J-Schleife zerstört, denn man sonst in der I-Schleife in der Variablen J abfragen kann (zu welchem Zeitpunkt ist J abgebrochen worden)! Außerdem könnte man so nie mehrere NEXTs überspringen. So steht es auch im Text und das Beispiel gehört gewissermaßen dazu.
Also ich werde das zurückändern, aber entsprechend im Beispiel kommentieren. --JohannKlasek 06:06, 13. Nov. 2009 (CET)
Ach, das ist ja interessant! Das hab ich mir ja noch nie so genau angeschaut, aber jetzt, wo du darauf hinweist, seh ich's auch. Stimmt! Der Stack wird sauber aufgeräumt! Cool! --GoDot 16:03, 13. Nov. 2009 (CET)

Was bedeutet denn (w) in (w) by jodigi 2006? --Pohli 13:59, 3. Sep 2006 (CEST)

Das (w) steht für written ähnlich dem (c) von copyright --Jodigi 15:11, 3. Sep 2006 (CEST)


Ich habe das nochmal gerade unter WinVice getestet 10 FORs kann man öffnen, aber schließt man das 10. korrekt mit NEXT, funktionieren nur noch 9 Schleifen ohne OUT OF MEMORY ! --Jodigi 00:07, 9. Nov. 2009 (CET)

Ich hab auch mit VICE getestet und bin nicht auf den Fall gestoßen, dass plötzlich nach 10 nur 9 Verschachtelungen möglich wären ... zumindest scheint es nicht der reguläre Fall sein. Wie sieht Dein Programm denn konkret aus?
Mir ist nur aufgefallen, dass bei 10 offenen FOR-Schleifen, der BASIC-Stack absolut voll ist. Führt man dann im innersten eine Operation durch, die den Stack benötigt (z.B. I=I+1), dann kommt freilich auch OUT OF MEMORY. Eine Leerschleife oder Befehle, die den Stack nicht brauchen, sollten da aber neutral sein. --JohannKlasek 01:15, 9. Nov. 2009 (CET)
Beispiel-Programm:
0 FOR A=0 TO 20
10 FOR B=0 TO 20
20 FOR C=0 TO 20
30 FOR D=0 TO 20
40 FOR E=0 TO 20
50 FOR F=0 TO 20
60 FOR G=0 TO 20
70 FOR H=0 TO 20
80 FOR I=0 TO 20
90 FOR J=0 TO 20
91 PRINT J,I,H,G,F,E,D,C,B,A
92 NEXT J,I,H,G,F,E,D,C,B,A

J entfällt beim 9er Schleifen ohne OUT OF MEMORY Einfach so eingegeben. --Jodigi 01:28, 9. Nov. 2009 (CET)


Wenn man's so eingibt funktioniert's....

0 FOR A=0 TO 2
10 FOR B=0 TO 2
20 FOR C=0 TO 2
30 FOR D=0 TO 2
40 FOR E=0 TO 2
50 FOR F=0 TO 2
60 FOR G=0 TO 2
70 FOR H=0 TO 2
80 FOR I=0 TO 2
90 FOR J=0 TO 2
92 NEXT J,I,H,G,F,E,D,C,B,A
100 PRINT J,I,H,G,F,E,D,C,B,A
110 GOTO 0

....also liegts am PRINT Befehl und zwar genau in $aaf8, dort wird mit php in der Print-Unterroutine "Ausführung von TAB" der Prozessorstatus auf den Stapel gerettet, der aber bummvoll ist. Jedenfalls seh ich das so.... --H.T.W 09:41, 9. Nov. 2009 (CET)
Nachsatz: Bei meinem Bsp (2 statt 20) dauert dies bei vollständigen Durchlauf mit VICE (2500% Speed) ca 10 sec. Wären dann mit 20 pro Schleife exp. 10 höher. Hab jetzt nicht nachgerechnet, aber schätze mal dass die Zeitdauer im 4-stelligen Bereich von Jahren liegt bis der arme C64-Emu das zu Ende gerechnet hat.... Aber schon mein Prof hat mir gesagt, dass ich ein erbärmlicher Mathematiker bin .... ;) --H.T.W 12:21, 9. Nov. 2009 (CET)

Ehm, ganau das hab ich ja oben (01:15, 9. Nov. 2009) bereits im Anschluss an meine Beobachtung auch angemerkt!
BTW: Der eigentliche Grund liegt an der Routine ab $A3FB, welche von FOR, GOSUB und Expressionevaluation aufgerufen wird, um mehr oder weniger "Worte" zu je 2-Bytes am BASIC-Stack zu reservieren. Gelingt dies nicht kommt die "OUT OF MEMORY"-Meldung. Deswegen geht z.B. in obigen Beispielen in der innersten Schleife ein PRINT; nicht aber ein PRINT " ";, weil wie hier schon wieder eine Ausdrucksauswertung haben ... Am PHP an der Stelle $aaf8 liegt es kaum, denn am Stack ist für jene Routinen, die nicht ineinander verschachtelt aufgerufen werden, an sich ausreichend Platz, damit gewährleistet ist, dass der Stapel nicht irgendwie korrumpiert wird und im BASIC-Interpreter Code nicht bei jedem Stack-Gebrauch auf einen Stack-Überlauf geprüft werden muss ... (Microsoft oder Commodore werden ja hoffentliche eine Deepest Stack Usage Analyse bei Interpreter und Kernal durchgeführt haben oder zumindest gut geschätzt haben, um die "Reserve" für CPU-Aktivitäten zu berücksichtigen ;) )
Tatsache bleibt jedenfalls, dass der Stack grundsätzlich 10 FOR-NEXT Verschachtelungen aufnehmen kann. Dass man dann in der Aktion für die innerste Schleife dann deutlich eingeschränkt ist, weil jedes Basic-Fragment, das aus welchen Gründen auch immer etwas am Stack zwischenspeichert nichts mehr reservieren kann, ist eine andere Sache. Freilich kann man diesen Umstand in einem Nebensatz von FOR, NEXT, Schleife oder auch Stapel gebührend anmerken. Z.B. kommt auch nicht die Tatsache besonders zum Vorschein, dass FOR-NEXT, "()", "GOSUB-RETURN" sich ein und den selben Stapel "teilen" und die max. Verschachtelung in je einem bestimmten Fall davon ausgeht, dass nichts und niemand sonst den Stapel irgendwie verwendet. --JohannKlasek 16:33, 9. Nov. 2009 (CET)
Hier steht, dass "bis zu 9" Verschachtelungsebenen erlaubt sind. Sicher aus den genannten Gründen. Bei 9 Ebenen bist du halt auf der sicheren Seite. Ich hab mal eben den FOR-Code überflogen ($A742): da werden jedes Mal (bei jedem FOR) mindestens 13 Bytes auf den Stack geschoben. --GoDot 22:43, 9. Nov. 2009 (CET)
Ja, auch wenn 10 Schleifen theoretisch, sowie praktisch geöffnet und wieder geschlossen werden können, macht es doch real keinen Sinn. Zumindestens in der innersten Schleife erfolgt eine Berechnung oder Befehlsaufrufe, die eventuell noch den Stack benötigen. Wir wollen ja u.a. auch, das der Leser fehlerfrei programmiert.
Schleifen sollen ja z.B. mehrere identische Befehle wiederholen und so das Proggrammieren erleuchtern. Somit müssen in irgendwelchen Schleifen Berechnungen oder Befehlsaufrufe erfolgen.
Vielleicht sollten wir das hier als Referenzprogramm nutzen, und wie gesagt, die reale Berechnung und der Befehlsaufruf ist auch drin:
0 Z=1
10 FOR A=11 TO 11
11 FOR B=11 TO 11
12 FOR C=11 TO 11
13 FOR D=11 TO 11
14 FOR E=11 TO 11
15 FOR F=11 TO 11
16 FOR G=11 TO 11
17 FOR H=10 TO 11
18 FOR I=1 TO 11
20 Z=J,I,H,G,F,E,D,C,B,A
21 PRINT CHR$(147); Z, I; H; G; F; E; D; C; B; A 
22 NEXT I,H,G,F,E,D,C,B,A
PS: Habe Sie mal verkürzt, wegen schnelleren Test ! --Jodigi 01:43, 10. Nov. 2009 (CET)--Jodigi 23:05, 9. Nov. 2009 (CET)
Nachtrag: Es geht sogar in der innersten Schleife bei diesem Beispiel ein GOSUB-Aufruf, wenn keine oder nur eine neue Variablen benutzt werden.
Die Nutzung von verschachtelten Funktionen im Unterprogramm führen aber auch hier zu einem OUT OF MEMORY. Wenn man sie einzeln nacheinander aufruft, geht es aber. --Jodigi 23:22, 9. Nov. 2009 (CET)
Das mit dem auf "der sicheren Seite liegen" ist mehr als vage, selbst wenn man 9 als Verschachtelungstiefe angibt. Denn egal in welcher Verschachtelungstief man sich befindet, kann mit der Kombination von verwendeten Unterprogrammaufrufen und Komplexität einer Ausdrucksauswertung mühelos immer wieder ein "OUT OF MEMORY" zustande kommen. Ich möchte die Angabe der max. möglichen Verschachtelungstiefe nicht falsch verstanden wissen. Es ist das, was es heisst: die maximal mögliche Anzahl der Verschachtelung, wenn auch unter bestimmten, idealen Bedingungen. Punkt. Eine etwaige Empfehlung, nicht an diese Grenze zu gehen, kann natürlich separat trotzdem gegeben werden. Es hängt eben von den konkreten Randbedingungen ab, wie wirksam die Empfehlung ist. Als Faustformel kann man freilich sagen, je weniger Verschachtelungstiefe jemand verwendet, desto mehr Verschachtelungen bei Ausdrücken und Unterprogrammaufrufen ist dann noch möglich, ohne dass das Programm mit "O O M" Error terminiert. Die Nennung von 10 als Maximum heisst ja noch lange nicht, dass man angehalten wird, bis an diese Grenze zu programmieren und dann auch noch die Erwartung zu haben, man könne dann alles machen, als wäre man nicht in der Verschachtelung. Aber das ist dann ein Thema für Programmiertechnik und Best Practice u.dgl.m., was man z.B. anhand von Beispielen anschneiden kann.
Zusammengefassst:
  • erlaubt (rein vom Machbaren) sind 10
  • empfohlen (für die Praxis) sind entsprechend weniger, abhängig davon, wie komplex der innerste Teil der verschachtelten Schleifen ist -hier eine konkrete Zahl anzugeben, halte ich nur bedingt für sinnvoll.
Das obige Referenzprogramm hilft da auch nicht weiter, bloß weil es genau einen Fall der bestimmten (10,10,24) Variationen (FOR-, Klammer-, GOSUB-Verschachtelungen), die den Stapel gerade nicht zum Überlauf bringt, zeigt. Die Grenze ist genau genommen keine einzelne Zahl, sondern eine räumlich aufgespannte Fläche
--JohannKlasek 13:07, 10. Nov. 2009 (CET)
Vielleicht sollte man das irgendwie erwähnen max. sind 10 geöffnete FORs möglich, allerdings praktisch u.a. wenn noch BASIC-Befehle und -Funktionen ausgeführt, das man max. 8-9 nur öffnet ! So ähnlich also wie Du beim GOSUB es angepaßt hast... --Jodigi 22:22, 10. Nov. 2009 (CET)