Programme récursif

Programme récursif - Ada - Programmation

Marsh Posté le 05-04-2009 à 16:40:42    

Bonjour,
 
Voici un petit programme récursif, simpliste, mais que je ne parviens pas trop à comprendre..
 

Code :
  1. procedure Test_Recursif is
  2.     procedure Test (N: in Integer) is
  3.     begin
  4.         if N /= 0 then
  5.             Test(N-1);
  6.         end if;
  7.         put(N,5);
  8.     end Test;
  9. begin
  10.     Test(4);
  11. end Test_Recursif;


 
A première vue, ce programme est censé renvoyer: 01234. Je ne saisis pas bien pourquoi, pourriez-vous me le détailler un peu svp?
 
Merci d'avance! :)  
 
 
 

Reply

Marsh Posté le 05-04-2009 à 16:40:42   

Reply

Marsh Posté le 05-04-2009 à 16:49:07    

dj_titeuf a écrit :

Je ne saisis pas bien pourquoi, pourriez-vous me le détailler un peu svp?


Déroules l'exécution à la main [:spamafote]
 
Et accessoirement, ça ne renvoie rien, ça affiche "0 1 2 3 4"


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 05-04-2009 à 17:17:09    

masklinn a écrit :


Déroules l'exécution à la main


Justement, c'est là où je bloque.. Voici comment je le comprends:
on a N=4: on vérifie donc bien N /=0, donc le programme s'appelle lui-même en prenant pour nouveau paramètre 4-1=3, etc, jusqu'à N=1. Et à partir de là, on afficherait donc simplement 1... Mais bon, ce raisonnement est incorrect apparemment! :(

Reply

Marsh Posté le 05-04-2009 à 17:30:22    

dj_titeuf a écrit :


Justement, c'est là où je bloque.. Voici comment je le comprends:
on a N=4: on vérifie donc bien N /=0, donc le programme s'appelle lui-même en prenant pour nouveau paramètre 4-1=3, etc, jusqu'à N=1. Et à partir de là, on afficherait donc simplement 1... Mais bon, ce raisonnement est incorrect apparemment! :(


La partie en gras est là où tu fais une grosse erreur.
 
Déroules la stack d'exécution à l'écrit, genre

Foo(X = 42)
    if 69 > X -> False
        Foo(X + 1) -> X = 43
            if 69 > X -> False
...



---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 05-04-2009 à 17:43:11    

Euh... Essayons d'aller plus doucement, du moins moi.
Pour N=4, la condition N/=0 est bien respectée, donc à priori, on rentre dans le if, Test(3) est alors appelé; on repart alors au begin, la condition est de nouveau vérifiée (3 /=0), puis Test(2) est appelé, puis alors Test(1). On repart au begin, la condition d'entrée est toujours vérifiée (1 /=0), alors Test(0) est appelé. Là par contre, la condition n'est plus vérifiée, on n'entre donc pas dans le if, et on se contente d'aller au put, qui affiche donc 0 (par contre, vu que c'est put(N,5), il devrait afficher un "blanc" en plus, à cause du 5 non?). Une fois parvenu ici, j'aurais eu tendance à dire que l'instruction se terminait..

Reply

Marsh Posté le 05-04-2009 à 17:44:21    

dj_titeuf a écrit :

Une fois parvenu ici, j'aurais eu tendance à dire que l'instruction se terminait..


Quelle instruction?


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 05-04-2009 à 17:51:58    

Enfin, je voulais dire, le programme général.. Mais encore une fois, ce n'est pas le cas, bien que je ne voie pas pourquoi..

Reply

Marsh Posté le 05-04-2009 à 17:57:23    

dj_titeuf a écrit :

Enfin, je voulais dire, le programme général..


Pourquoi ça ferait un truc pareil [:pingouino dei]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 05-04-2009 à 18:00:07    

Parce que le programme a "fini"? On est allé jusqu'au cas N=0, et on a affiché 0, je ne vois pas ce qu'il peut faire d'autre ensuite..

Reply

Marsh Posté le 05-04-2009 à 18:01:25    

dj_titeuf a écrit :

Parce que le programme a "fini"? On est allé jusqu'au cas N=0, et on a affiché 0, je ne vois pas ce qu'il peut faire d'autre ensuite..


Bah continuer à exécuter le programme, il reste plein de trucs pas exécutés si on remonte la call stack


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 05-04-2009 à 18:01:25   

Reply

Marsh Posté le 05-04-2009 à 18:03:40    

Et bien, ce doit être là que mon problème de compréhension se situe... Peut-être pourrais-tu m'expliquer stp?

Reply

Marsh Posté le 05-04-2009 à 18:15:54    

dj_titeuf a écrit :

Et bien, ce doit être là que mon problème de compréhension se situe... Peut-être pourrais-tu m'expliquer stp?


On va étendre le contenu de Test_Recursif:

Code :
  1. Test(4)


On va utiliser le modèle de substitution de Structure and Interpretation of Computer Programs (je recommande d'ailleurs fortement de le lire)

 

Donc si on substitue le contenu de Test à cet appel, on se retrouve avec

Code :
  1. if 4 /= 0 then
  2.    Test(4-1);
  3. end if;
  4. put(4,5);


Ligne 2 on a un Test, donc on continue à substituer

Code :
  1. if 4 /= 0 then
  2.    if 3 /= 0 then
  3.        Test(3-1);
  4.    end if;
  5.    put(3,5);
  6. end if;
  7. put(4,5);


et encore

Code :
  1. if 4 /= 0 then
  2.    if 3 /= 0 then
  3.        if 2 /= 0 then
  4.            Test(2-1);
  5.        end if
  6.        put(2, 5);
  7.    end if;
  8.    put(3,5);
  9. end if;
  10. put(4,5);


et encore

 
Code :
  1. if 4 /= 0 then
  2.    if 3 /= 0 then
  3.        if 2 /= 0 then
  4.            if 1 /= 0 then
  5.                Test(1-1);
  6.            end if
  7.            put(1, 5);
  8.        end if
  9.        put(2, 5);
  10.    end if;
  11.    put(3,5);
  12. end if;
  13. put(4,5);


et encore

Code :
  1. if 4 /= 0 then
  2.    if 3 /= 0 then
  3.        if 2 /= 0 then
  4.            if 1 /= 0 then
  5.                if 0 /= 0 then
  6.                    Test(0-1);
  7.                end if
  8.                put(0, 5);
  9.            end if
  10.            put(1, 5);
  11.        end if
  12.        put(2, 5);
  13.    end if;
  14.    put(3,5);
  15. end if;
  16. put(4,5);


Ici, on a 0 /= 0 qui est true, donc Test(0-1) n'est jamais exécuté, donc on a pas besoin de l'étendre, et on peut simplifier l'expression développée en retirant toute la condition:

Code :
  1. if 4 /= 0 then
  2.    if 3 /= 0 then
  3.        if 2 /= 0 then
  4.            if 1 /= 0 then
  5.                put(0, 5);
  6.            end if
  7.            put(1, 5);
  8.        end if
  9.        put(2, 5);
  10.    end if;
  11.    put(3,5);
  12. end if;
  13. put(4,5);


On exécute ça séquentiellement, et on voit bien qu'on se retrouve avec put(0, 5); put(1, 5); put(2, 5); put(3, 5); put(4, 5);


Message édité par masklinn le 05-04-2009 à 18:16:56

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 05-04-2009 à 18:20:33    

Merci beaucoup pour tous ces détails! En fait, je pensais qu'une fois le premier put effectué, le programme se terminait, alors qu'en fait, il semble revenir au début..

Reply

Marsh Posté le 05-04-2009 à 18:22:34    

dj_titeuf a écrit :

il semble revenir au début..


non.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 05-04-2009 à 18:25:03    

Ah... Bon, je vais lire et relire tranquillement tes explications, et tenter de mieux cerner le principe. Encore merci.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed