Au premier abord, en récursif, la fonction factoriel s'écrit
- Code: Tout sélectionner
int fact(n)
début
si n = 0 alors
1
sinon
n * fact(n - 1)
fin
Que constate-t-ton ?
Que pour calculer fact(n) , on calcule d'abord fact(n-1) puis on multiplie le résultat obtenu par n.
Les appels successifs s'empilent pour pouvoir exécuter le code, car à la fin d'un appel il faut faire une multiplication.
Avec la version avec accumulateur, plus besoin d'empiler les appels :
- Code: Tout sélectionner
int fact(n)
fact_acc(n, 1)
int fact_acc(n, acc)
si n = 0 alors
acc
sinon
fact_acc(n-1, n * acc)
Lorsque n = 0 on renvoie directement la valeur de l'accumulateur, plus de calculs pour le retour.
exemple
fact(3) ==> fact_acc(3, 1)
fact_acc(3, 1)
n 0 donc on renvoie fact_acc(3-1, 3 * 1) soit fact_acc(2,3)
fact_acc(2, 3)
n 0 donc on renvoie fact_acc(2-1, 2 * 3) soit fact_acc(1,6)
fact_acc(1, 6)
n 0 donc on renvoie fact_acc(1-1, 1 * 6) soit fact_acc(0,6)
fact_acc(0, 6)
n = 0 donc on renvoie 6
Quel est l'intérêt ? le compilo détecte cette récursion "terminale" et donc transforme le calcul en traitement itératif.