PDA

Visualizza la versione completa : [C++] Traduzione di codice con GOTO, GOSUB, ecc. da linguaggio BASIC


RooccoXXI
12-02-2011, 00:48
Ciao a tutti.

Sto leggendo alcuni vecchi programmi in BASIC che mi piacerebbe riscrivere in C++ ma non ci capisco una mazza.

La struttura del programma la seguente:


// Dichiarazione e inizializzazione variabili
GOSUB 100
END
100 IF (...) GOTO 200
// Istruzioni
GOTO 300
200 // Istruzione
GOSUB 100
// Istruzioni
GOSUB 100
// Istruzioni
GOSUB 100
// Istruzioni
GOSUB 100
// Istruzione
300 RETURN


A cosa servono l'istruzione GOSUB e RETURN, esattamente?!

Proprio non riesco a capire il flusso del programma... :dh:

RooccoXXI
12-02-2011, 16:46
Ah, dimenticavo! Dovrebbe essere un processo ricorsivo quello implementato dal programma in BASIC!

lolide
12-02-2011, 17:10
Originariamente inviato da RooccoXXI
Ciao a tutti.

Sto leggendo alcuni vecchi programmi in BASIC che mi piacerebbe riscrivere in C++ ma non ci capisco una mazza.

La struttura del programma la seguente:


// Dichiarazione e inizializzazione variabili
GOSUB 100
END
100 IF (...) GOTO 200
// Istruzioni
GOTO 300
200 // Istruzione
GOSUB 100
// Istruzioni
GOSUB 100
// Istruzioni
GOSUB 100
// Istruzioni
GOSUB 100
// Istruzione
300 RETURN


A cosa servono l'istruzione GOSUB e RETURN, esattamente?!

Proprio non riesco a capire il flusso del programma... :dh:

:facepalm:
Non una cosa difficilissima, basta tradurre dall'inglese :old:
GOSUB non ti sembra anche a te una specie di call come in assembly (come un goto solo che esiste un return)?
RETURN .... it's simply return :D non c' nient'altro da aggiungere

Dopo l'inizializzazione delle variabili, va all'etichetta 100, esegue l'if. se vera la condizione va all'etichetta 200 senn alla 300 (se va alla 300 esce perch c' un RETURN). Se va alla 200 invece esegue le istruzioni e fa un goto alla 100, dove rif l'if fin quando quella condizione vera, continua a ciclare.

Se non capisci sto codice, meglio se lasci perdere :mame:
:ciauz:

RooccoXXI
12-02-2011, 18:21
Originariamente inviato da lolide
:facepalm:
Non una cosa difficilissima, basta tradurre dall'inglese :old:
GOSUB non ti sembra anche a te una specie di call come in assembly (come un goto solo che esiste un return)?
RETURN .... it's simply return :D non c' nient'altro da aggiungere

Dopo l'inizializzazione delle variabili, va all'etichetta 100, esegue l'if. se vera la condizione va all'etichetta 200 senn alla 300 (se va alla 300 esce perch c' un RETURN). Se va alla 200 invece esegue le istruzioni e fa un goto alla 100, dove rif l'if fin quando quella condizione vera, continua a ciclare.

Se non capisci sto codice, meglio se lasci perdere :mame:
:ciauz:

L'istruzione RETURN non termina il programma. Per quello c' l'istruzione END. E appunto non capisco come il programma fa a ritornare all'istruzione END. Inoltre GOSUB non capisco cosa fa esattamente! Perch in teoria tutte le quattro istruzioni prima dei GOSUB dovrebbero venire eseguite allo stesso livello...!

Perch lasciar perdere?! Voglio solo capirci qualcosa in questo cavolo di "spaghetti code"!

lolide
12-02-2011, 18:33
Originariamente inviato da RooccoXXI
L'istruzione RETURN non termina il programma. Per quello c' l'istruzione END.

Infatti volevo dire che esce dalla funzione non dal programma.

Originariamente inviato da RooccoXXI
E appunto non capisco come il programma fa a ritornare all'istruzione END.


Dopo l'inizializzazione delle variabili c' un GOSUB: lo spiego meglio perch non hai capito, GOSUB, tradotto dall'inglese, vuol dire "vai sotto". Pi nello specifico con GOSUB intende che va in una funzione. Quando in quella funzione arriva al return (fin quando l'if e' falso) torna alla linea dopo il GOSUB quindi esce con END.


Originariamente inviato da RooccoXXI
Inoltre GOSUB non capisco cosa fa esattamente! Perch in teoria tutte le quattro istruzioni prima dei GOSUB dovrebbero venire eseguite allo stesso livello...!


Purtroppo senza sapere quali sono le altre "Istruzioni" non si pu sapere cosa fa di preciso.

Cmq tutti quei gosub richiamano ricorsivamente la funzione.


Originariamente inviato da RooccoXXI
Perch lasciar perdere?! Voglio solo capirci qualcosa in questo cavolo di "spaghetti code"!


Quello che volevo dire che fai quello che vuoi, ma quelle sono basi.
Cio almeno ad "intuire" il funzionamento del codice traducendo dall'inglese ;)
E inoltre che comunque il basic cos a basso livello, quindi se non capisci questo figuriamoci le altre istruzioni.
:ciauz:

MItaly
12-02-2011, 18:34
GOTO un salto incondizionato.
GOSUB una primitiva chiamata a funzione, salta da un'altra parte e, quando viene chiamato RETURN, ritorna all'istruzione successiva al GOSUB
Per dirla in un'altra maniera, quando usi GOSUB viene messo sullo stack l'instruction pointer (che contiene l'indirizzo dell'istuzione successiva), quindi viene effettuato un GOTO alla locazione specificata; il RETURN prende dallo stack l'ultimo indirizzo messo e fa un GOTO ad esso.
GOSUB e RETURN, come ti stato detto, sono i corrispondenti dell'assembly CALL (PUSH EIP + JMP) e RET (POP + JMP).

RooccoXXI
12-02-2011, 20:23
Il programma il seguente, preso dal libro Fractals fot the classroom - Part one: Introduction to fractals and chaos [Peitgen, Jrgens, Saupe; Springer-Verlag, 1992; p. 207]. Il suo scopo quello di disegnare la curva di Koch.

DIM xleft(10), xright(10), yleft(10), yright(10)
INPUT "Peak offset (0.29):", r
level = 5
xleft(10) = 30
xright(10) = 30 + 300
yleft(10) = 190
yright(10) = 190
GOSUB 100
END
REM DRAW AT LOWEST LEVEL OF RECURSION
100 IF level > 1 GOTO 200
LINE (xleft(1), yleft(1)) - (xright(1), yright(1))
GOTO 300
REM BRANCH INTO LOWER LEVELS
200 level = level - 1
REM LEFT BRANCH
xleft (level) = xleft (level + 1)
yleft (level) = yleft (level + 1)
xright (level) = 0.333 * xright (level + 1) + 0.667 * xleft (level + 1)
yright (level) = 0.333 * yright (level + 1) + 0.667 * yleft (level + 1)
REM MIDDLE LEFT BRANCH
xleft (level) = xright (level)
yleft (level) = yright (level + 1)
xright (level) = 0.5 * xright (level + 1) + 0.5 * xleft (level + 1) - offset * (yleft (level + 1) - yright (level + 1))
yright (level) = 0.5 * yright (level + 1) + 0.5 * yleft (level + 1) - offset * (xleft (level + 1) - xright (level + 1))
REM MIDDLE RIGHT BRANCH
xleft (level) = xright (level)
yleft (level) = yright (level)
xright (level) = 0.667 * xright (level + 1) + 0.33 * xleft (level + 1)
yright (level) = 0.667 * yright (level + 1) + 0.33 * yleft (level + 1)
REM RIGHT BRANCH
xleft (level) = xright (level)
yleft (level) = yright (level)
xright (level) = xright (level + 1)
yright (level) = yright (level + 1)
level = level + 1
300 RETURN

Per malgrado le vostre spiegazioni non riesco a capire come funziona esattamente (e quindi come tradurlo in C++ dove i GOTO, fortunatamente, non esistono! :) )

MItaly
12-02-2011, 20:35
Cosa c' alla linea 300?

RooccoXXI
12-02-2011, 20:41
Originariamente inviato da MItaly
Cosa c' alla linea 300?

Scusa, per sbaglio non l'ho postato tutto.

Ecco il programma completo:

DIM xleft(10), xright(10), yleft(10), yright(10)
INPUT "Peak offset (0.29):", r
level = 5
xleft(10) = 30
xright(10) = 30 + 300
yleft(10) = 190
yright(10) = 190
GOSUB 100
END
REM DRAW AT LOWEST LEVEL OF RECURSION
100 IF level > 1 GOTO 200
LINE (xleft(1), yleft(1)) - (xright(1), yright(1))
GOTO 300
REM BRANCH INTO LOWER LEVELS
200 level = level - 1
REM LEFT BRANCH
xleft (level) = xleft (level + 1)
yleft (level) = yleft (level + 1)
xright (level) = 0.333 * xright (level + 1) + 0.667 * xleft (level + 1)
yright (level) = 0.333 * yright (level + 1) + 0.667 * yleft (level + 1)
REM MIDDLE LEFT BRANCH
xleft (level) = xright (level)
yleft (level) = yright (level + 1)
xright (level) = 0.5 * xright (level + 1) + 0.5 * xleft (level + 1) - offset * (yleft (level + 1) - yright (level + 1))
yright (level) = 0.5 * yright (level + 1) + 0.5 * yleft (level + 1) - offset * (xleft (level + 1) - xright (level + 1))
REM MIDDLE RIGHT BRANCH
xleft (level) = xright (level)
yleft (level) = yright (level)
xright (level) = 0.667 * xright (level + 1) + 0.33 * xleft (level + 1)
yright (level) = 0.667 * yright (level + 1) + 0.33 * yleft (level + 1)
REM RIGHT BRANCH
xleft (level) = xright (level)
yleft (level) = yright (level)
xright (level) = xright (level + 1)
yright (level) = yright (level + 1)
level = level + 1
300 RETURN

MItaly
12-02-2011, 20:56
Il blocco da 100 a 300 come se fosse una procedura; la parte tra 100 e 200 come se fosse un if-else al contrario.

Il punto qui che il blocco "grosso" della procedura a logica andrebbe eseguito pi volte, ma non vedo nessun GOTO 100, per cui partendo da level=5 la procedura viene eseguita una volta, vengono riempiti i vari array solo relativamente al livello corrente e il programma termina. :confused:

... comunque, questo codice strutturato come se fosse assembly. :spy:

Loading