Newsgroup: it.comp.lang.visual-basic
Titolo: Ricorsione !!!!

Ciao a tutti,
premetto che sono un programmatore C e che solo nell'ultimo periodo mi sto
avvicinando a VB.
Ho un problema con la ricorsione:
cioè una variabile locale definita all'interno di una procedura ricorsiva,
non mantiene il valore giusto.
C'è qualche settaggio particolare da eseguire?
Che cosa è lo stack overflow?
Grazie D.K.

 Che cosa č lo stack overflow?
Ma non sei un programmatore C ?
Hai esaurito lo spazio di memoria indirizzabile per il
processo corrente.
Forse la tua procedura ricorsiva "ricorre" troppo.

Devi dichiarare la variabile Static se vuoi che mantenga il valore (non č
cosě anche in C?).
Lo "stack overflow" č il rimpimento dello stack di chiamata, cioč un buffer
nel quale vengono memorizzate le informazioni quando esegui una call ad una
routine e che permette al programma di ripristinare la situazione quando
ritorna alla chiamante. Nello stack finiscono varie cose fisse (indirizzo
del chiamante etc.) e le variabili passate alla funzione. Se ne evince che
si dovrebbero passare pochi argomenti in chiamate ricorsive. Chiaramente
dipende dal numero di ricorsioni - 
p.es
. se implementi un QuickSort
ricorsivo e tenti di ordinare 100.000 elementi vai di sicuro in overflow,
anche se passi pochi parametri. In questi casi si usa una versione non
ricorsiva dell'algoritmo, piů brutta ma piů efficiente (fra l'altro la
ricorsione č spesso un fattore di rallentamento, perché una call costa molto
piů di un Goto).
----------------------------------------------------------------------
Stefano Minardi
zet...@mclink.it
----------------------------------------------------------------------

 più di un Goto).
molto più brutta, molto più efficiente...
il GOTO andrebbe abolito :) , certo ti permette di ottimizzare il codice, ma
per i puristi è un'eresia!
del resto è ovvio che laddove sia possibile implementare una funzione
iterativa al posto di una ricorsiva nel 99% dei casi essa è più efficiente!
---
byeZ
Alessandro Cerioni
- Sunspot "TSK Squad" 
www.tsksquad.net
aiutamici co-webmaster 
http://www.aiutamici.com

riferimento!
ByVal = Per Valore
ByRef = Per Riferimento
Ciao

Ciao di nuovo a tutti,
Essendo io un programmatore C, conosco perfettamente che cosa si intende per
stack overflow in ambiente C; ho ipotizzato una gestione particolare in VB.
Comunque il problema è il seguente:
Ho una variabile locale dichiarata all'interno della funzione ricorsiva.
Tale variabile locale al ritorno da una chiamata ricorsiva, invece di
mantenere il "vecchio" valore cioè quello relativo al proprio "record di
attivazione" si comporta in modo strano e cioè come se fosse una variabile
definita static. Eseguendo il debug della variabile mi accorgo che,
all'uscita di una chiamata ricorsiva, alla variabile locale viene attribuito
un valore Nothing invece di quello che prima vi era prima della chiamata
ricorsiva.
Grazie per la vostra attenzione D.K.

...

Nothing?
E' una var. che referenzia un oggetto?
La usi la Option Explicit?
Se tu fai una funzione così:
Function Ricorsiva(ByVal n As Integer)
    Dim i As Integer
    i = 10
    n = n \ 2
    If (n > 1) Then
        Call Ricorsiva(n)
    End If
    Call MsgBox(i) <=== Scrive 10
End Function
quindi ti mantiene il valore corretto.
Ciao

 ha scritto nel messaggio
news:898foi$fu0$1...@nslave1.tin.it...

appunto come dicevo io :) forse l'ho detto male io o tu hai capito male ;)
intendevo proprio dire che lo stack overflow è molto più probabile quando si
passano variabili tramite BYVAL alla procedura ricorsiva
e che CMQ se non è importante che per ogni sessione la variabile abbia uno
specifico valore, allora è anche meglio dichiarala a livello di modulo con
condivisone di tipo shared :) concordi?
è CMQ strano che condoscendo il C non si sappiano i livelli di esistenza e
di condivisione o visibilità degli oggettii (siano esse funzioni o dati) il
C è mitico per le cose che ci può fare proprio sotto questo punto di vista!
:)
---
byeZ,


 End Function
si okkey, ma ogni volta che richiami la funzione viene allocato nuovo spazio
per gestire la variabile "i", in questo caso sarebbe piů corretto
dichiararee "i" a livello di modulo e non interna alla funzione, se poi si
presuppone che le chiamate possono essere tante, va aggiunto che
un'ulteriore ottimizzazione sia di stack che di prestazioni la si ottiene
passando "n" per riferimento e quindi se il valore della variabile da
comunicare deve essere mantenuto la chiamata alla funzione sarebbe:
let appoggio=pippo
call Ricorsiva (appoggio)
cosě che su pippo il valore non ti cambia!
ma poi che funzione č se non ritorna alcun valore ???
;)


per i puristi è un'eresia!
Beh, giusto una questione di stile, perche' se devo ottimizzare fortemente
una routine, il goto lo uso eccome (in assembler non ci sono costrutti come
while :-) Molti anni fa ricordo di aver visto del codice illeggibile perche'
ai programmatori (che provenivano dal Fortran) non era stato insegnato l'uso
di goto in C: erano convinti che non esistesse. I loro istruttori non lo
avevano menzionato perche' screditato. Il risultato era che in alcune
routine venivano fatti salti mortali per uscire 'castamente' da cicli di
while (variabili settate 'artificialmente' etc.).
Quando ci vuole, ci vuole.


Quando ci vuole, ci vuole.
Intanto non si può più pensare la programmazione in modo procedurale come ai
tempi del QBasic o del Pascal, se lo si fa ancora allora non serve il goto,
ma una nuova ottica di programmazione.
Se non è così significa che i suddetti algoritmi erano o scritti male in
partenza o i linguaggio non disponeva di sistemi "intelligenti" (non conosco
il fortran).
Comunque in VB, nonostante quello che dicono i "nostalgici" l'unico caso in
cui il Goto è necessario è la gestione degli errori, ed è rimasto solo per
compatibilità.
Lo stesso help riporta:
Nota   La presenza di troppe istruzioni GoTo può rendere difficile la
lettura e il debug del codice. Quando possibile, è consigliabile
utilizzareistruzioni di controllo strutturate (Do...Loop, For...Next,
If...Then...Else, Select Case).
Ciao

 Lo stesso help riporta:
CUT (vabbé questo lo sappiamo tutti!)
io ancore specifico l'assegnamento con l'inutile [LET] :) figurati come sono
ridotto ;) eheheh
però ti garantisco che il codice è molto più leggibile!
---
byeZ,
Alessandro Cerioni
- Sunspot "TSK Squad" 
www.tsksquad.net
aiutamici co-webmaster 
www.aiutamici.com

però ti garantisco che il codice è molto più leggibile!
Secondo me è più leggibile senza, comunque sembra che il LET consenta al
compilatore di ottimizzare un pochino l'assegnazione poichè capisce al volo
che l'uguale è un'assegnazione e non un confronto: come saprai il basic è
l'unico linguaggio che usa lo stesso simbolo per assegnazione e confronto,
il cui significato cambia solo dal contesto.
Ciao

ma una nuova ottica di programmazione.
Non vedo cosa c'entri la programmazione procedurale con il GOTO. Io scrivo
codice non procedurale da un sacco di tempo (moooolto prima di VB e di
Windows) e ho sempre usato il GOTO *quando* serviva.


solo in routine Time-Critical.
Intendiamoci, non e' che io dica "usate il GOTO perche' e' un'istruzione
fondamentale". Quando io scrvo codice, il GOTO ci casca spesso, ma non uso
piu' di una-due label per funzione (effettivamente per lo piu' per uscire in
caso di errore di una funzione chiamata, quindi le label sono identiche in
tutte le funzioni, ho anzi un Addin che mi costruisce lo scheletro della mia
funzione-tipo). Neppure dico che serva a ottimizzare - non in VB, comunque,
dove l'ottimizzazione e' per lo piu' superflua (e' terribile in ogni caso).
In questo caso pensavo piuttosto a linguaggi un pochino di piu' basso
livello, dove il GOTO viene brutalmente tradotto in una jump dell'assembler.
Insomma, intendiamoci, io sono forse uno dei peggio rimpiballe sullo stile
del codice (se non e' formattato come dico io sono dolori) ma qualche GOTO
non e' la fine del mondo - basta che non si scrivano programmi tipo:
If (a > b) Then GOTO AmaggB
If (b>c) Then GOTO BmaggC
If (c>d) Then GOTO CmaggD
...etc.
A volte, pero', si sente la necessita' di una cosa del genere *proprio per
la leggibilita' del codice*, perche' se fra i vari IF intercorrono piu' di 5
righe a me da' fastidio, specialmente se si tratta di un IF/ELSE/ENDIF o di
un SELECT, perche' ogni spezzone di codice e' troopo grande, la visibilita'
d'insieme si annulla (proprio quello che accade con il GOTO) e perche'
voglio isolare ogni sezione. Ma in questi casi la soluzione non e':
If (a > b) Then
    Una tonnellata di codice
Endif
If (b>c) Then
    Un'altra tonnellata di codice
Endif
etc.
ma piuttsoto:
If (a > b) Then
    AmaggB()
Endif
etc.
Indubbiamente piu' leggibile e ortodosso del GOTO, ma ditemi dove sta questa
grande perspicuita'? C'e' anche un vizio in questo, cioe' l'eccesso di call.
Ho visto programmi (alcuni ben fatti) nei quali era impossibile seguire la
catena delle chiamate ( a call b, b call c, c call d...). Codice cosi' mica
e' tanto dominabile, no? Tuttavia e' facile che capiti anche per caso - io
tendo a questo abuso, 
p.es
., perche' fondamentalmente odio sezioni piu'
lunghe di una schermata, massimo due: il codice lo voglio vedere tutto
insieme.


Windows) e ho sempre usato il GOTO *quando* serviva.
E non è il caso di adeguarsi ai nuovi sistemi?
Il fatto è proprio che il Goto NON serve...
D'altra parte "per scrivere un programma servono solo tre strutture:
assegnazione, selezione (if) e un loop".
Ciao.

 il cui significato cambia solo dal contesto.
Che le benedizioni del tuo Dio scendano su di te e la tua famiglia! Ora mi
sento meno rimbambito e meno pedante.
--
Ciao.
Maurizio

 assegnazione, selezione (if) e un loop".
eddaì non esagerare... più roba c'hai a disposizone meglio è!!! :)
facciamo una petizione affinché Bill metta nel VB7 prossimo i puntatori, il
C-union e l'operatore ternario?
così potremmo programmare il VB come fosse il C  :))


 sento meno rimbambito e meno pedante.
questo lo sapevo, CMQ grazie per la riconferma!


cosě potremmo programmare il VB come fosse il C  :))
E allora finalmente mi installerei il C++ che ho qui sullo scaffale a
riempirsi di polvere :)
Ciao

 :)
mi auguro che almeno sia stato lessato. e non cosparso d'olio o altri lipidi
allo stato brado.
(d'altronde anche il c.d. spaghetti programming prevede oggetti cotti, seno'
e' linearissimo, no?).

assegnazione, selezione (if) e un loop".
In alcuni linguaggi non esistono cicli di loop, che veramente sono superflui
e possono essere raramente ottimizzati.


capire capisca!
E daie! Ma cos'è questa storia del GOTO e delle lontane tecniche di
programmazione? Dieci anni fa il GOTO era screditato come adesso e 15 anni
fa c'erano linguaggi non procedurali che consentivano il multitasking quando
alla Microsoft sviluppavano ancora il Basic per la Commodore e Xerox e Apple
si contendevano senza avversari il mondo Windows. Non è che ora, perché
avete uno straccio di linguaggio come VB, potete fare gli schizzinosi.
PS: fra l'altro, in VB esiste effettivamente l'operatore IIF che (invece) io
trovo molto comodo in sostituzione di
IF/THEN/ELSE - 
p.es
.:
If bType Then
    chkCheck.Value=vbChecked
Else
    chkCheck.Value=vbUnchecked
Endif
non mi pare più bello e leggibile di:
chkCheck.Value = IIF(bType, vbChecked, vbUnchecked)
Se non si usa IIF si rischia di tornare indietro di un milione di anni !-)


 routine.
La penso/avo anche io come te. La scorsa estate avevo postato un messaggio
sul newsgroup chiedendo se il Gosub si poteva ancora usare e ne era
scaturito un bel thread di messaggi.
Comunque alla fine il problema maggiore del gosub č che č lentissimo nel
codice compilato. Cioč, nell'IDE o compilando in pseudo codice č + veloce
della chiamata a funzione, mentre nel compilato finale č decisamente +
lento. Ricordo che erano state fatte tutte le prove del caso, mi pare fosse
stato Roal a farle, ma non vorrei sbagliarmi e non ho + il messaggio
originale.
Resto comunque d'accordo con te sulla filosofia. Se ti serve una funzione
che venga chiamata piů volte solo all'interno di una unica procedura, č piů
leggibile il gosub. Questione di gusti, ovviamente, non vorrei che Zanna mi
mordesse per questa mia affermazione. 8-)
Ciao
*Roby*

mordesse per questa mia affermazione. 8-)
Basta, ho deciso di non mordere più nessuno.
Mi sto rendendo conto che nel NG ultimamente (anche a causa mia, dev'essere
l'influenza -spero passeggera- di qualche cattiva stella) ci sono degli
atriti ed anzichè aiutarci ci stiamo scannando a vicenda.
Poi chi legge i messaggi (mi ci metto sempre anch'io) se la prende sempre in
modo personale.
Che ognuno scriva come preferisce, d'altra parte ognuno ha esigenze diverse.
Se poi uno mette ancora i numeri di linea nel codice (lo suggerisce
addirittura il libro -consultabile su MSDN- Advanced Microsoft Visual Basic
5 della Microsoft Press. Ho letto cose allucinanti in questo libro) che
faccia pure. Peccato che VB non supporti la keyword asm, come il delphi, per
poter scrivere codice assembly...
Ciao
P.S.: Il gosub l'ho sempre trovato scomodo anche in Basic e le riserve su di
lui sono le stesse che sul Goto, anzi pote- hem- DOVEndo scegliere userei il
goto.
Quando scrivevi in besic ho solo usato il Goto, ma io sono passato
direttamente dal vecchio M$Dos per home computer al pascal e poi a C e VB,
saltando il QBasic.

 goto.
Beh, Goto e Gosub non sono intercambiabili. Il secondo veniva usato come
chiamata a funzione quando le funzioni non erano disponibili. Per simularlo,
di goto ne servono 2.
Comunque hai ragione, ormai è un retaggio del passato. Però è difficile
disabituarsi ad utilizzare le cose che una volta sembravano il massimo della
comodità.
Ciao
*Roby*

 riempirsi di polvere :)
io ho VS, però trovo ostica l'interfaccia e la costrizione ad usare API del
C, una volta col DOS usavo QC2.5, QCX (del MSC Compiler) e me la cavavo (ho
anche scritto un manule :) mai pubblicato)... la programmazione ad oggetti
la conosco nel concetto, applicat sommariamente con VB e le sue classi che
pià che oggetti sono oggettini :)
---


IF-THEN-ELSE, CMQ è vero che con IFF guadagni molta leggibilità!
io uso molto spesso IIf... sicuro che è molto lento? per informazione...
grazzzzz
Faber

> > "Faber"

Qui dice che IIf e' tre volte piu' lenta:
http://www.vb2themax.com/Item.asp?PageID=TipBank&ID=122
Sarebbe interessante pero' valutare la somma di tutte le istruzioni
necessarie per ottenere lo stesso scopo:
A)
Dim a, b, c, d, e
Let a = espressione
Let c = espressione
Let d = espressione
If a Then Let b = c Else Let b = d
Let e = Calcola(b)
B)
Dim a, c, d, e
Let a = espressione
Let c = espressione
Let d = espressione
Let e = Calcola(IIf(a, c, d))
--
Ciao.
Maurizio


lo sapevo anch'io e per aver semplicemente letto il manuale, mi pare sulla
parte dove parla di come ottimizzare il codice... praticamente hanno messo
un'istruzione bella che però sconsigliano in quanto molto lenta... bah, chi
ci capisce è bravo, e proprio non riesco a capire come faccia ad esser lenta
visto che è stata creata per gestire una caso specifico di IF/THEN/ELSE...
secondo me alla Microsoft quando hanno scritto il codice della IFF il
programmatore non dormiva da una settimana! :)
per fare le prove che hai postato basta che usi un loop molto lungo e fai
analizzare i risultati dal Code Profiler!


analizzare i risultati dal Code Profiler!
grazissimo per questo consiglio, era proprio ciň di cui avevo bisogno.
un'altra cosa perň di cui avrei bisogno č.... uhmmm.... cos'č il Code
Profile?  :)    č un programma, lo posso scaricare da qualche parte?
grazie!!!!!!
Faber

 stufo!
Trovo piu' riposante SHIFT+INS.
--
Ciao.
Maurizio

 ha scritto nel messaggio
news:8a854i$ggj$1...@nslave1.tin.it...

:) oops, scusa ho sbagliato...
ovvio che CTRL+INS serve per copiare e SHIFT+INS per incollare, mentre
SHIFT+DEL per tagliare :)


 problema...
[...]
Visto come, mediamente, sono descritti i problemi nelle conversazioni da ng
c'e' da tremare all'idea.
--
Ciao.
Maurizio

Scusate se mi intrometto, tardi, nella discussione ma il problema di velocita' di IF e IIF
mi ha incuriosito.
Ho misurato, con mio vecchio programma per valutare la velocita' del codice, le seguenti
due versioni:
    Static a As Boolean
    a = IIf(a, False, True)
e:
    Static a As Boolean
    If a Then
        a = False
    Else
        a = True
    End If
con i risultati:
  IF  0.325 [microsecondi] piu'/meno 0.002  [microsecondi] al 95% di confidenza.
  IIF 2.151 [microsecondi] piu'/meno 0.005  [microsecondi] al 95% di confidenza.
L' IIF risulterebbe circa sette volte piu' lento dell' IF.
Ho provato con un PC con Pentium III a 500 [MHz] sotto Windows NT4.
Saluti a tutti.
Franco


 > IF-THEN-ELSE, CMQ è vero che con IFF guadagni molta leggibilità!
---


 grazie!!!!!!
cerca o sull'HD o sul CDROM di VB4 (mi pare che col 5 o 6 non ci fosse più)
il programma VBCP32.EXE,
eseguilo, poi esegui il VB, da quel momento in poi lo potrai usare quando
vuoi in quanto dovresti trovarlo tra le aggiunte! per l'uso c'è il wizard...
è molto semplice, puoi monitorare le singole procedure e tante altre cose
interessanti!


usata in routines time-critical
Forse nelle routine time-critical sarebbe bene non usare nessuna delle
istruzioni di VB.
