CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

Fonction récursive (factorielle)

EileenBelserion
EileenBelserion
Niveau 7
27 janvier 2019 à 23:47:52

Salut,
Alors voila, j'ai la fonction factorielle codé comme ca

int factorielle(int n)
{
   return n == 1 ? 1 : n * factorielle(n - 1);
}

Je suppose qu'on ne met jamais d'entier négatif, c'est juste pour l'exemple.
Du point de vue de l'ordinateur, comment il exécute cette fonction ? (les fonctions récursif en général) :(
Pour moi logiquement, il lit l'instruction, il appelle la fonction factorielle avec l'argument (n-1) etc etc
mais d'après mon prof c'est pas du tout comme ca que ca se passe réellement :noel:
malheureusement il n'a pas donné plus d'explication :(

godrik
godrik
Niveau 30
28 janvier 2019 à 01:57:14

Ca depend du langage. Dans un langage comme le C, avec un compilateur basique, tu as raison, c'est comme ca que la fonction est execute.

Ici, la fonction est recursive terminale. Donc le compilateur peut faire de la derecursivation et retirer l'appel recursif en transformant en boucle for. Je te laisse le pointeur wikipedia qui va bien: https://en.wikipedia.org/wiki/Tail_call

Batora
Batora
Niveau 10
28 janvier 2019 à 03:38:30

Alors pour comment l'ordinateur interprète ca on peut pas le savoir en ayant seulement le code, ca dépend entièrement de l’implémentation. A priori l'optimisation d'une fonction récursive finale c'est possible comme le dit mon vdd, pour ca essaye de comparer le code compilé avec optimisations de ton bout de code et d'un bout de code similaire utilisant une boucle.

godrik
godrik
Niveau 30
28 janvier 2019 à 04:21:09

Ou plus simplement, lit l'assembleur directement et voit si il fait un appel recursif ou pas.

]Mewtwo[
]Mewtwo[
Niveau 10
01 février 2019 à 12:38:01

Le programme va utiliser une zone mémoire qui lui est réservé la pile d’exécution ou stack en anglais. Quand il va lire factorielle (n-1) il va empiler dans cette zone l'adresse de retour de la fonction courante et puis appeler factorielle (n-1) et ainsi de suite jusqu'à ce qu'il renvoie 1. A ce moment là il va dépiler l'adresse de retour de la fonction précédente, multiplier le résultat, puis dépiler l'adresse précédente etc. Jusqu'à la première factorielle.

On voit que si la récursivité est trop grande il y a un risque de sur-remplir la pile ce qui ferait planter le programme. Une autre façon de faire c'est la récursivité terminale. Par exemple ici la fonction factorielle récursive terminale : à chaque appel il n'y a pas besoin d'empiler l'adresser de retour car il n'y a plus rien à calculer dans la fonction courante.

int factorielle(int n, int a)
{
   return (n == 0) ? a : factorielle(n-1,a*n);
}
Type2Engineer
Type2Engineer
Niveau 9
02 février 2019 à 22:38:56

Le 28 janvier 2019 à 01:57:14 godrik a écrit :
Ca depend du langage. Dans un langage comme le C, avec un compilateur basique, tu as raison, c'est comme ca que la fonction est execute.

Ici, la fonction est recursive terminale. Donc le compilateur peut faire de la derecursivation et retirer l'appel recursif en transformant en boucle for. Je te laisse le pointeur wikipedia qui va bien: https://en.wikipedia.org/wiki/Tail_call

La fonction de l'auteur est non terminale, celle de ]Mewtwo[ l'est.

godrik
godrik
Niveau 30
03 février 2019 à 04:16:44

multiplication est associative, le compilateur devrait savoir faire la transformation.

J'ai jamais essaye en C, mais un compilateur lisp d'il y a 15 ans savait faire la transformation.

Sous forums
  • Aide à l'achat Mac
  • Création de Jeux
  • Linux
  • Programmation
  • Création de sites web
  • Internet
  • Steam Deck
  • Macintosh
  • Hardware
La vidéo du moment