Punto informatico Network
Login Esegui login | Non sei registrato? Iscriviti ora (è gratuito!)
Username: Password:
  • Annuncio Pubblicitario

[Bash] Funzione ricorsiva - Esempio poco chiaro

Il forum per tutti i developer. Leggere attentamente il regolamento di sezione prima di postare.

[Bash] Funzione ricorsiva - Esempio poco chiaro

Messaggioda alphacentauri » gio feb 18, 2010 12:53 am

Ciao a tutti.
In una discussione nella sezione relativa a linux mi è stata suggerita questa guida http://bash.cyberciti.biz/guide/Main_Page che mi sono pappato con piacere, ma proprio alla fine - sarà anche l'ora - non riesco a venirne fuori con questo esempo: http://bash.cyberciti.biz/guide/Recursive_function
Si parla appunto di funzioni ricorsive, e secondo il debug offerto, lo script si comporta in maniera comprensibile fino a quando il valore di i diventa due ed echo lo visualizza, però non capisco perché non finisca tutto qui. E invece f comincia ad essere moltiplicato per i valori precedentemente assunti da i... qualcuno saprebbe suggerirmi il perché? [8)]
Per comodità riporto anche lo script che in questo caso viene lanciato con ./nomescript.sh 5:
Codice: Seleziona tutto
#!/bin/bash
# fact.sh - Shell script to to find factorial of given command line arg
factorial(){
  local i=$1
  local f
  declare -i i
  declare -i f
 
  # factorial() is called until the value of $f is returned and is it is <= 2
  # This is called the recursion
  [ $i -le 2 ] && echo $i || { f=$(( i - 1)); f=$(factorial $f); f=$(( f * i )); echo $f; }
}
 
 
# display usage
[ $# -eq 0 ] && { echo "Usage: $0 number"; exit 1; }
 
# call factorial
factorial $1

Chiedo scusa se la domanda è stupida, ma sono sprovveduto in materia... [:-H]
grazie a chi vorrà aiutarmi e ciao agli altri
Avatar utente
alphacentauri
Neo Iscritto
Neo Iscritto
 
Messaggi: 22
Iscritto il: sab feb 09, 2008 7:03 pm

Re: [Bash] Funzione ricorsiva - Esempio poco chiaro

Messaggioda ninjabionico » gio feb 18, 2010 5:35 am

Ciao.

A me sembra funzioni egregiamente...

#!/bin/bash
# fact.sh - Shell script to to find factorial of given command line arg
factorial(){
local i=$1 alla variabile locale i viene memorizzato il valore passato alla chiamata
local f la variabile f è un'altra variabile locale
declare -i i le due variabili sono dichiarate come interi
declare -i f

# factorial() is called until the value of $f is returned and is it is <= 2
# This is called the recursion
[ $i -le 2 ] esegue il controllo i<=2
&& echo $i se i è minore o uguale a 2 restituisce come valore della funzione la variabile i
|| altrimenti...
{ f=$(( i - 1)); a f assegna i-1
f=$(factorial $f); a f assegna il valore della funzione factorial di i-1 (che è il valore di f alla chiamata)
f=$(( f * i )); a f assegna il fattoriale di i-1, che ora è contenuto in f, moltiplicato per i che da come risultato il fattoriale di i
echo $f; } restituisce come valore della funzione factorial il contenuto di f
}


# display usage controllo di inzio script
[ $# -eq 0 ] se il numero degli argomenti passati è 0
&& { echo "Usage: $0 number"; exit 1; } allora stampa il messaggio ed esci con valore 1 (che normalmente segnala un errore)

# call factorial
factorial $1 esegue la funzione passandogli come valore il primo argomento



[ciao]
Io dico le cose così come stanno! Questo è il mio credo ninja - by Naruto Uzumaki
Expert-Advanced User Powered by Gnu/Linux
Avatar utente
ninjabionico
Membro Ufficiale (Gold)
Membro Ufficiale (Gold)
 
Messaggi: 5207
Iscritto il: lun mar 20, 2006 10:51 pm
Località: Prov. Pd

Re: [Bash] Funzione ricorsiva - Esempio poco chiaro

Messaggioda alphacentauri » gio feb 18, 2010 9:58 am

Grazie mille per la risposta!
Ok, da quel che hai scritto ne ricavo che il senso delle singole parti dovrei avercelo avuto, ma quel che mi sfugge allora è la sintassi dello funzione... Per spiegarmi riporto l'esempio del sito con i vari passaggi e li commento:

Codice: Seleziona tutto
+ '[' 1 -eq 0 ']'   #si inizia con [ $# -eq 0 ]
+ factorial 5      #la funzione prende 5 come argomento
+ local i=5      #attribuito il valore
+ local f      #viene introdotta la variabile f
+ declare -i i      #dichiarazione come quella successiva per i e f interi
+ declare -i f
+ [[ 5 -le 2 ]]      #viene controllato il valore 5<=2 [ $i -le 2 ]
+ f=4         #siccome è false si passa oltre l'operatore OR
++ factorial 4      #f=$(( i - 1)); e quindi 5-1
++ local i=4      #nuove operazioni con le vaiabili
++ local f
++ declare -i i
++ declare -i f
++ [[ 4 -le 2 ]]   #di nuovo 4<=2 false quindi si riparte
++ f=3         
+++ factorial 3
+++ local i=3
+++ local f
+++ declare -i i
+++ declare -i f
+++ [[ 3 -le 2 ]]   #3<=2 false e si riparte
+++ f=2
++++ factorial 2
++++ local i=2
++++ local f
++++ declare -i i
++++ declare -i f
++++ [[ 2 -le 2 ]]   #finalmente 2<=2, in questo caso =
++++ echo 2      #siccome è true si esegue echo $i dopo l'operatore &&
+++ f=2         #???? Non dovrebbe essere finito qui con echo ????
+++ f=6
+++ echo 6
++ f=6
++ f=24
++ echo 24
+ f=24
+ f=120
+ echo 120
120

Voglio dire, se [ $i -le 2 ] è true e per questo viene eseguito echo $i, quel che sta dopo OR non dovrebbe essere scartato? I valori di f successivi immagino vengano da f=$(( f * i )); che in effetti per come la metto io non verrebbe mai eseguito... ???? e qui casco io, ergo l'asino.
Avatar utente
alphacentauri
Neo Iscritto
Neo Iscritto
 
Messaggi: 22
Iscritto il: sab feb 09, 2008 7:03 pm

Re: [Bash] Funzione ricorsiva - Esempio poco chiaro

Messaggioda ninjabionico » ven feb 19, 2010 2:38 am

...
...
++++ [[ 2 -le 2 ]] #finalmente 2<=2, in questo caso =
++++ echo 2 #siccome è true si esegue echo $i dopo l'operatore && Ora si ritorna indietro all'ultima chiamata della funzione factorial che restituisce 2
+++ f=2 #???? Non dovrebbe essere finito qui con echo ???? Ovvero f=factorial 2 e così f vale 2
+++ f=6 Poi diventa f=$f*$i che è 2*3 ovvero f diventa 6
+++ echo 6 Ora si ritorna indietro ancora alla precedente chiamata della funzione factorial che restituisce 6
++ f=6 Come prima f=factorial 3 e così f ora vale 6
++ f=24 C'è bisogno di dire f=$f*$i che è 6*4 e f diventa 24?
++ echo 24 Si ritorna ancora una volta alla precedente chiamata della funzione factorial che ora restituisce 24
+ f=24 Come ormai avrai capito f=factorial 4 ora vale 24
+ f=120 Ennesimo f=$f*$i che è 24*5 e f diventa 120
+ echo 120 Ecco l'ultima uscita dalla funzione, ovvero quella che risponde alla 1° chiamata della funzione stessa e restituisce 120
120 Visualizzazione a schermo del valore 120


Come avrai capito, la funzione ricorsiva richiama se stessa in modo da annidarsi...
... semplifica la scrittura del codice che diventa più facilmente leggibile e semplice, ma non è conveniente dal punto di vista delle prestazioni ne dallo spreco di risorse.

[ciao]
Io dico le cose così come stanno! Questo è il mio credo ninja - by Naruto Uzumaki
Expert-Advanced User Powered by Gnu/Linux
Avatar utente
ninjabionico
Membro Ufficiale (Gold)
Membro Ufficiale (Gold)
 
Messaggi: 5207
Iscritto il: lun mar 20, 2006 10:51 pm
Località: Prov. Pd

Re: [Bash] Funzione ricorsiva - Esempio poco chiaro

Messaggioda alphacentauri » sab feb 27, 2010 2:08 pm

Anche se in ritardo grazie per la risposta. Prima di riprendere in mano la guida è passato qualche giorno, e mi ha fatto bene. Finalmente ho capito, è solo che nella mia zucca il concetto di annidamento era molto particolare [acc2] ... pensavo che ogni volta si desse vita ad un processo nuovo, mentre quello "genitore" ne risultasse in definitiva sostituito... bastava farsi un disegnino in testa di cos'è l'annidamento... comunque grazie, adesso sto leggendo un'altra guida e poi cerco risvolti pratici nei feed di commandlinefu.com che è spesso interessante.
grazie ancora e bye
Avatar utente
alphacentauri
Neo Iscritto
Neo Iscritto
 
Messaggi: 22
Iscritto il: sab feb 09, 2008 7:03 pm


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Nessuno e 0 ospiti

Powered by phpBB © 2002, 2005, 2007, 2008 phpBB Group
Traduzione Italiana phpBB.it

megalab.it: testata telematica quotidiana registrata al Tribunale di Cosenza n. 22/09 del 13.08.2009, editore Master New Media S.r.l.; © Copyright 2008 Master New Media S.r.l. a socio unico - P.I. 02947530784. GRUPPO EDIZIONI MASTER Spa Tutti i diritti sono riservati. Per la pubblicità: Master Advertising