Domanda

Mi rendo conto che potrebbe sembrare una domanda sciocca, ma l'ultima volta che l'ho programmato era in assembler, quindi il mio pensiero potrebbe essere spento:

Una funzione ricorsiva in questo modo:

def fac(n):
    if n == 0:
        return 1
    else:
        return n * fac(n - 1)

Perché quando la funzione raggiunge n == 0 non restituisce 1 ma piuttosto la risposta che è fattoriale. Sto pensando a qualcosa come nell'assemblatore sarebbe quando n == 0:

mov eax, 1
ret

Perché il codice sopra funziona, suppongo che python restituisca l'ultimo valore nello stack prima di quella condizione?

È stato utile?

Soluzione

Pensa in questo modo, ad esempio per fac (5) :

return 5 * fac(4)
           return 4 * fac(3)
                      return 3 * fac(2)
                                 return 2 * fac(1)
                                            return 1 * fac(0)
                                                       1

Quindi 1 sarà il primo valore restituito ma verrà restituito a fac (1) e fac (1) verrà restituito a fac (2) e così via.

Altri suggerimenti

restituisce 1 quando n == 0. Quel valore di ritorno viene estratto dallo stack dal sito chiamante, che era l'invocazione in n * fac (n - 1) . Quel 1 viene moltiplicato per n e restituito, ecc.

Se chiami fac (0) restituirà 1 (non 0, ma suppongo che sia solo un refuso nella tua domanda). Se chiami fac (1), andrà nella clausola else e lì chiamerà fac (0) . Questo restituirà 1. Quindi calcolerà n * 1, che è 1, e lo restituirà. Se chiami fac (2) andrà anche nella clausola else, dove chiamerà fac (1) che come menzionato sopra restituirà 1, quindi n * fac (n-1) sarà 2 e questo è il valore di ritorno di fac (2) . E così via. Spero che sia spiegato per te.

Non viene restituito in modo implicito nulla: quando n = 0, la funzione immette l'istruzione if e restituisce 1 direttamente dall'istruzione return 1 . Tuttavia, questo non è il punto in cui la risposta "quotata" è fattoriale viene restituito all'utente. Al contrario, potrebbe restituire questo valore a chiamata funzione invocata da fac (1), che nel mezzo del ramo n * fac (n - 1) . Quindi ci vorrà il "1" restituito e restituito n * 1 , ovvero da 1 a è chiamante. Se questo è fac (2), restituirà n * 1 o 2 in è chiamante e così via.

Così fac (5) viene tradotto come:

fac(5) = 5 * fac(4) = 5 * (4 * fac(3) = 5 * (4* (3 * fac(2)) = 5 * (4* (3 * (2 * fac(1)) = 5 * (4* (3 * (2 * (1 * fac(0)) = 5*4*3*2*1*1

Solo dopo che il valore 1 viene restituito attraverso ogni livello superiore, ritorna al primo chiamante e la moltiplicazione in ogni fase fornisce la risposta.

James, quando la chiamata finale alla tua funzione (quando n == 0) ritorna è solo una delle diverse istanze di fac (n) nello stack di chiamate. Se dici print (fac (4)), lo stack è essenzialmente:

fac(0)
fac(1)
fac(2)
fac(3)
fac(4)
print()

L'ultima chiamata a fac (0) restituisce appropriatamente 1, tuttavia in Python hai richiesto il valore di ritorno della prima chiamata a fac (n), fac (4).

Non pensarlo come un ciclo in cui scoppierà 'ret', il ritorno conclude semplicemente una delle diverse esecuzioni in sospeso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top