Partage
  • Partager sur Facebook
  • Partager sur Twitter

Limite à la récursivité d'une fonction.

Y'en a une ?

    14 avril 2006 à 19:25:27

    Salut a tous !

    Ma question est simple : Est-ce qu'une fonction peut s'appeller elle même indefiniment ?

    Pour le savoir, j'ai fais ça :

    #include <stdio.h>

    void test(int) ;

    void main()
    {
        test(1) ;
    }

    void test(int x)
    {
        printf("%ld\n",x) ;
        test(x+1) ;
    }


    Comme ça je vois combien de fonctions test se sont "emboitées".

    Chez moi, ça donne ça : 130190 appels.

    Mais c'est valables pour tout les ordi, ou non ??
    • Partager sur Facebook
    • Partager sur Twitter
      14 avril 2006 à 19:36:19

      oui, tu dois mettre un conditon si tu ne veux plus la laisser tourner

      autrement, ca dépend, mais je penses qu'il y a des restrictions a la récursivités (sécurité anti DOS)

      pour avoir essayé une fonction de hackman avec de la récursivité, je peux te dire qu'elle n'est pas infinie (OS? limite sur les entiers utilisés, je ne sais pas trop)
      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        14 avril 2006 à 20:15:09

        La seule limite c'est la place que l'OS (système d'exploitation) windows ou linuw ou Mac os X (ca dépant ce que tu as :p)a allouer pour ton programe.
        Donc dés que tu as plus de place disponible pour emplier les environements de tes appel ca plante en te disant memoir insufisante quelque chose comme ca.
        Pour info quand tu appel une fonction dans la mémoire il est crée une zone avec toutes les variables de ton programes les paramètre de ta fonction ... c'est ce que l'on appelle l'environement de la fonction.

        Donc ca dépand de ta fonction (la taille de lenvironement ) et de ton os
        • Partager sur Facebook
        • Partager sur Twitter
          14 avril 2006 à 20:17:01

          Stack overflow ça te dit rien ?
          Chaque fois qu'une fonction est appelée, elle est placée en haut d'une pile de fonctions, quadn elle se termine, elle est dépilée.

          Pour une fonction récursive non contrôlée, les appels successifs font que la fonction est empilée à l'infini ... du moins pour un ordinateur possedant une mémoire vive infinie...

          Donc logiquement la mémoire vive doit être un des facteurs d'engorgement de la pile de fonctions.
          • Partager sur Facebook
          • Partager sur Twitter
            14 avril 2006 à 20:21:48

            Citation : simboubou

            Ma question est simple : Est-ce qu'une fonction peut s'appeller elle même indefiniment ?


            La réponse est hélas un peu plus compliquée. En fait, cela dépend de la quantité de mémoire vive disponible. Au bout d'un moment, il y a surcharge de la pile (stack overflow) et donc impossibilité d'appeler une nouvelle fonction, d'où crash.

            En fait, quand ton programme entre dans une fonction (enfin un bloc en fait), il réserve dans la "pile" la place nécessaire pour les variables utilisées dans cette fonction, ainsi que la "stack frame", avec notamment l'adresse de retour (pour qu'à la fin de la fonction, le programme retourne où il en était avant son lancement). Les parties réservées à chaque appel finissent par remplir la pile (stack en Anglais) et là ça plante.

            Voici un code qui devrait t'éclairer :

            #include <stdio.h>

            /* Fonction récursive, prenant en paramètre la profondeur actuelle */
            void test(int x)
            {
                /* Ici, on affiche une ligne contenant la profondeur actuelle */
                printf("test(%d) : %p\n",x,
                    &x); /* Et l'adresse de x, pour pouvoir voir le
                    remplissement de la pile ; noter que les adresses décroissent,
                    car la pile se rempli à l'envers */


                /* Appel récursif de test() avec une profondeur évidement incrémentée */
                test(x+1);
            }

            /* Procédure principale */
            int main()
            {
                /* Premier appel de la fonction récursive test() avec une profondeur de 0 */
                test(0);
               
                /* Fin du programme ; cette instruction ne va jamais être exécutée car
                le programme sera fermé avant */

                return 0;
            }

            Désolé de la complexité de ma réponse, mais elle a le mérite d'être suffisament complète. Ta question est très intéressante, et pour connaître la réponse il est bien souvent nécessaire d'avoir des bases en assembleur (comme moi).
            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              14 avril 2006 à 20:24:16

              Citation : remram44


              Désolé de la complexité de ma réponse, mais elle a le mérite d'être suffisament complète. Ta question est très intéressante, et pour connaître la réponse il est bien souvent nécessaire d'avoir des bases en assembleur (comme moi).


              Les bases en assembleur ne sont pas requise mais une bonne compréhantion de ce qui ce passe en mémoir central lors des apelle de fonctions ! (mais bon si on a les bases en assembleur c'est plsu simple !)
              • Partager sur Facebook
              • Partager sur Twitter
                14 avril 2006 à 20:46:42

                Il faut savoir que GCC/G++ n'utilise pas les push et pop standard et gère la pile lui-même, en modifiant le pointeur et en lisant/écrivant lui-même. Pour ce qui est de la notion de pile, on apprend logiquement cela en étudiant la théorie de l'assembleur (c'est là qu'on se plonge dans le fonctionnement interne qu'on évite en C++ et qui peut rester obscure même si on fait du C).
                • Partager sur Facebook
                • Partager sur Twitter
                  14 avril 2006 à 20:53:50

                  Citation : simboubou

                  Salut a tous !
                  Ma question est simple : Est-ce qu'une fonction peut s'appeller elle même indefiniment ?


                  Non. Un appel récursif doit être borné, sinon, le comportement est indéfini. La limite absolue dépend de l'implémetation. La limite réelle pour une implémentation donnée dépend des circonstances (nombre d'appels précédents...). C'est très difficilement prévisible. En tout cas, pas de manière portable.

                  Conclusion, la récursivité, c'est esthétique mais c'est pas sûr (à moins de mettre des limites intrinsèques, ce qui nuit beucoup à l'intérêt de la méthode...). Toujours préférer une solution itérative. C'est beaucoup plus stable (si on y met les moyens).

                  Citation : simboubou


                  Pour le savoir, j'ai fais ça :

                  #include <stdio.h>

                  void test(int) ;

                  void main()
                  {
                      test(1) ;
                  }

                  void test(int x)
                  {
                      printf("%ld\n",x) ;
                      test(x+1) ;
                  }



                  Comme ça je vois combien de fonctions test se sont "emboitées".

                  Chez moi, ça donne ça : 130190 appels.

                  Mais c'est valables pour tout les ordi, ou non ??


                  Non.
                  (XP/MinGW)

                  Si ça se trouve, minGW a optimisé en itératif (je compile en -O2) et la boucle n'a pas de limite...

                  Ctrl-C à 58 000 000 ...
                  RAS.
                  • Partager sur Facebook
                  • Partager sur Twitter
                  Music only !
                  Anonyme
                    14 avril 2006 à 20:54:54

                    En meme temps moi j'ai vu ca en algorithme et pas en c ni en C++ et puis apres plus en détaile en Ansembleur c'est trés interrésant d'ailleur !
                    Moi j'aime bien comme il appelle les fonctions (toutes la sauvegarde du contextes donc des registres ~ enviroment )
                    C'est toujours bien de savoir un peu pres comment il t'aloue la mémoire et comme il gère ca car ca peut te permettre de faire moi d'erreur et peu etre d'aller plus vite !
                    • Partager sur Facebook
                    • Partager sur Twitter
                      14 avril 2006 à 20:58:55

                      Citation : remram44

                      Il faut savoir que GCC/G++ n'utilise pas les push et pop standard et gère la pile <...>


                      Ces détails d'implémentation dépendent de l'architecture et de l'humeur de celui qui écrit le back-end... On ne peut pas généraliser...
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Music only !
                        15 avril 2006 à 5:44:59

                        je comprend mieux pourquoi mon programme qui calcul la factoriel d'un nombre a des probleme avec les grand nombres quand j'utilise une foction recursive! par contre avec une boucle, je n'ai pas eu de problème.

                        Pour apprendre l'assembleur, vous avez des liens?
                        • Partager sur Facebook
                        • Partager sur Twitter

                        Limite à la récursivité d'une fonction.

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown