IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Problème récursivité avec gcc -Wall


Sujet :

C

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 24
    Points : 15
    Points
    15
    Par défaut Problème récursivité avec gcc -Wall
    Bonjour,

    En fait voila, j'ai envie de créer un petit algo en C qui calculerait le carré d'un nombre. Bien sûr tout ceci est assez simple, je peux faire ça par exemple.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int
    carre(int n){
     
      return n*n;
    }
    Mais j'ai voulu compliqué un peu les choses. Sachant qu'une multiplication peut être considérée comme une suite d'addition.
    Par exemple: 7*7=49 équivaut à 7+7+7+7+7+7+7=49. Pourquoi ne pas reproduire le même procédé pour le carré d'un nombre ainsi:
    7²=7+7+7+7+7+7+7=49, n'est-ce pas? Pour faire cet algo, j'ai décidé d'utiliser le principe de la récursivité. Alors oui je sais pour ce type de problème la récusivité est plutôt déconseillée, mais j'ai décidé de le faire uniquement pour faire travailler ma cervelle et rien d'autres.
    J'ai donc ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    #include<stdio.h>
     
    int
    carre2(int n){
     
      carre2bis(n,n);
      return 0;
    } 
     
    int
    carre2bis(int n,int m){
     
      if(n==1){
        return 0;
      }
      return m + carre2(n-1);
    } 
     
    int
    main(void){
     
      printf("%d\n",carre2(8));
     
      return 0;
    }
    Cette fonction fonctionne relativement bien pour tant quand je compile avec l'option -Wall j'ai un warining du type:

    carre.c: Dans la fonction «carre2» :
    carre.c:16: attention : déclaration implicite de la fonction « «carre2bis» »

    Comment faire pour ne plus avoir cette érreur? Un define?

    Je vous remercie d'avance pour vos réponses.

  2. #2
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Bonjour er bienvenue sur ce forum.
    Première chose, comme tu peux le voir, ton code est très mal affiché, il faut l'encadrer par les balises (bouton # de l'éditeur).
    Pour ton problème, celà vient simplement du fait que tu n'as pas déclaré ou défini la fonction carre2bis avant son utilisation.
    Tu peux simplement déplacer le code de cette fonction avant le code de carre2 et tout compilera correctement.

  3. #3
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Trap D
    Tu peux simplement déplacer le code de cette fonction avant le code de carre2 et tout compilera correctement.
    Hélas, le problème se reportera alors sur la définition de carre2 dans carre2bis.

    Place un prototype de la fonction carre2bis en tête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include<stdio.h>
    int carre2bis(int n,int m);
     
    int carre2(int n){   
      carre2bis(n,n); // il faudrait peut être faire quelque chose 
                          //avec la valeur de retour !
      return 0;
    } 
     
    int carre2bis(int n,int m){
    ...
    }

  4. #4
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Points : 4 637
    Points
    4 637
    Par défaut
    Citation Envoyé par alcibiade Voir le message
    Cette fonction fonctionne relativement bien pour tant quand je compile avec l'option -Wall j'ai un warining du type:
    Indépendamment du warning dont l'explication a ete fournie, pour moi cette fonction ne calcule pas le carre d'un nombre:

    * carre2() retourne toujours 0 et non le nombre calcule
    * la condition d'arrêt de la récursivité n'est pas la bonne
    * a chaque nouvelle itération, tu décrémentes bien le nombre d'essai restant mais aussi le nombre a élevé au carré (puisque la fonction carre2() n'a qu'un seul argument représentant les deux, pourquoi la récursion ne se fait-elle pas exclusivement avec la fonction carre2bis() ?)

  5. #5
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Points : 6 498
    Points
    6 498
    Par défaut
    Citation Envoyé par diogene Voir le message
    Trap D
    Hélas, le problème se reportera alors sur la définition de carre2 dans carre2bis.

    Place un prototype de la fonction carre2bis en tête

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include<stdio.h>
    int carre2bis(int n,int m);
     
    int carre2(int n){   
      carre2bis(n,n); // il faudrait peut être faire quelque chose 
                          //avec la valeur de retour !
      return 0;
    } 
     
    int carre2bis(int n,int m){
    ...
    }
    Efectivement, je n'avais pas fait attention à la récursivité croiséee

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 145
    Points : 170
    Points
    170
    Par défaut
    Citation Envoyé par alcibiade Voir le message
    Mais j'ai voulu compliqué un peu les choses. Sachant qu'une multiplication peut être considérée comme une suite d'addition.
    Par exemple: 7*7=49 équivaut à 7+7+7+7+7+7+7=49. Pourquoi ne pas reproduire le même procédé pour le carré d'un nombre ainsi:
    7²=7+7+7+7+7+7+7=49, n'est-ce pas? Pour faire cet algo, j'ai décidé d'utiliser le principe de la récursivité.
    Excuse-moi, mais de la façon dont tu présentes la chose ci-dessus, il s'agirait plutôt d'une démarche itérative et pas tellement récursive.

    Pourrais-tu nous détailler ton algo ?

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 24
    Points : 15
    Points
    15
    Par défaut Merci pour vos réponses.
    Bonjour,

    Je voudrais d'abord vous remercier pour vos réponses, car grâce à elles, j'ai pu trouver ce qui n'allait pas.

    Tout d'abord, il est vrai que la fonction carre2 renvoyée toujours 0. J'ai donc modifié ainsi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     
    int
    carre2(int n){
     
      return carre2bis(n,n);
     
    }
    En ce qui concerne la fonction carre2bis, je me suis trompé en la collant. Je l'ai donc changé comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int
    carre2bis(int n,int m){
     
      if(n==0){
        return 0;
      }
      return m + carre2bis(n-1,m);
    }
    Enfin j'ai rajouté ce que vous m'avez proposé ; j'ai déclaré la fonction en dessous du #include.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    #include<stdio.h>
    int carre2bis(int n,int m);
    Je n'ai donc plus de problèmes de compilation et la fonction semble fonctionner correctement. Bien sûr, elle génère encore des erreurs avec des valeurs comme -1 par exemple, j'ai un SEGMENTATION FAULT, mais je ne suis pas très loin de la terminer. Je vous remercie donc encore une fois et à plus.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    145
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2008
    Messages : 145
    Points : 170
    Points
    170
    Par défaut
    Bien

    Une simple suggestion.... change le nom de ta fonction carre2bis() et appelle la plutot quelque chose comme multiplication()

  9. #9
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Bien sûr, elle génère encore des erreurs avec des valeurs comme -1 par exemple, j'ai un SEGMENTATION FAULT
    avec n <0 , la condition de sortie n==0 ne sera jamais remplie.

    On peut envisager, par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    int carre2bis(int n,int m)
    {
      if(n==0) return 0;
      if(n<0)
      {
         n = -n;
         m= -m;
      }
      return m + carre2bis(n-1,m);
    }
    - La fonction continuera de planter pour des valeurs élevées de n où il y aura un dépassement de pile lié à la récursivité.
    - Le résultat peut être erroné lorsqu'il ne tient pas dans un int.

  10. #10
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par alcibiade Voir le message
    Mais j'ai voulu compliqué un peu les choses. Sachant qu'une multiplication peut être considérée comme une suite d'addition.
    Par exemple: 7*7=49 équivaut à 7+7+7+7+7+7+7=49. Pourquoi ne pas reproduire le même procédé pour le carré d'un nombre ainsi:
    7²=7+7+7+7+7+7+7=49, n'est-ce pas? Pour faire cet algo, j'ai décidé d'utiliser le principe de la récursivité. Alors oui je sais pour ce type de problème la récusivité est plutôt déconseillée, mais j'ai décidé de le faire uniquement pour faire travailler ma cervelle et rien d'autres.
    J'ai donc ceci:
    <...>
    Cette fonction fonctionne relativement bien
    Ton code ne fonctionne pas du tout... y'a pas de 'relativement'. Ca marche ou ça marche pas. Point.
    pour tant quand je compile avec l'option -Wall j'ai un warining du type:

    carre.c: Dans la fonction «carre2» :
    carre.c:16: attention : déclaration implicite de la fonction « «carre2bis» »
    Tu m'étonnes...
    Comment faire pour ne plus avoir cette érreur? Un define?
    Il faut cesser de coder au hasard... Il y a des règles en C. Notamment une entité (code, donnée) doit être déclarée avant usage.

    D'autre part, la recursivité, a aussi ses règles...

    Bref, ceci fonctionne (dans des limites raisonnables).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    #include<stdio.h>
     
    int carre_r (int n, int m)
    {
       if (n == 1)
       {
          return 0;
       }
       return m + carre_r (n - 1, m);
    }
     
    int carre (int n)
    {
       return carre_r (n, n);
    }
     
    int main (void)
    {
       printf ("%d\n", carre (8));
     
       return 0;
    }

  11. #11
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par diogene Voir le message
    Trap D
    Hélas, le problème se reportera alors sur la définition de carre2 dans carre2bis.
    Ca c'est un autre problème. Son code est faux. Point.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    int
    carre2bis(int n,int m){
     
      if(n==1){
        return 0;
      }
      return m + carre2(n-1);
    }
    C'est pas carre2(), mais carre2bis() (noms à la gomme détectés...)

  12. #12
    Membre averti Avatar de GyZmoO
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    428
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 428
    Points : 301
    Points
    301
    Par défaut
    Salut à tous !

    [Edit] Mais qu'est qu'il se passe si on demande le carré de 1 avec cette méthode ?? Ca renvoit 0 ?[/Edit]

  13. #13
    Expert éminent sénior

    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    10 610
    Détails du profil
    Informations personnelles :
    Âge : 66
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 10 610
    Points : 17 916
    Points
    17 916
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par GyZmoO Voir le message
    Salut à tous !

    [Edit] Mais qu'est qu'il se passe si on demande le carré de 1 avec cette méthode ?? Ca renvoit 0 ?[/Edit]

  14. #14
    Membre éprouvé Avatar de orfix
    Homme Profil pro
    Inscrit en
    Avril 2007
    Messages
    707
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Maroc

    Informations professionnelles :
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 707
    Points : 1 132
    Points
    1 132
    Par défaut
    Citation Envoyé par Emmanuel Delahaye Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
    #include<stdio.h>
     
    int carre_r (int n, int m)
    {
       if (n == 1)
       {
          return 0;
       }
       return m + carre_r (n - 1, m);
    }
     
    int carre (int n)
    {
       return carre_r (n, n);
    }
     
    int main (void)
    {
       printf ("%d\n", carre (8));
     
       return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int carre_r (int n, int m)
    {
       if (n == 0)
       {
          return 0;
       }
       return m + carre_r (n - 1, m);
    }

  15. #15
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par ssmario2 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int carre_r (int n, int m)
    {
       if (n == 0)
       {
          return 0;
       }
       return m + carre_r (n - 1, m);
    }
    Oui, c'est possible, j'ai surtout cherché à rendre le bouzin compilable... C'est vrai que 8 x 8 = 56, ça m'a laissé perplexe, mais comme je suis pas fort en math, j'ai pas insisté ! Pas mon boulot.

Discussions similaires

  1. problème compilation avec gcc real(kind=16)
    Par djocin dans le forum Fortran
    Réponses: 2
    Dernier message: 01/07/2010, 10h39
  2. [linux] problème d'inclusion avec gcc
    Par wtfu dans le forum C
    Réponses: 3
    Dernier message: 12/07/2006, 14h49
  3. Problème pour compiler avec gcc
    Par Mick.Zen dans le forum Autres éditeurs
    Réponses: 2
    Dernier message: 28/06/2006, 14h05
  4. Réponses: 5
    Dernier message: 09/04/2006, 19h02
  5. Petit problème avec GCC pour l'Unicode...
    Par Nico*3-3 dans le forum Autres éditeurs
    Réponses: 6
    Dernier message: 29/01/2006, 17h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo