Partage
  • Partager sur Facebook
  • Partager sur Twitter

fonction est pointeur

    12 août 2019 à 4:22:59

    Bonsoir

    Alors voila j'ai un premiers programme qui converti les degrés 

    int  main()
     {
        int max;
        int min;
        int inter;
        int fah;
        int cel;
        
        max = 300;
        min = 0;
        inter = 20;
        
        fah = min;
        while (fah <= max)
        {
            cel = (fah-32) * 5 / 9;
            printf("%d\t%d\n", fah, cel);
            fah = fah + inter;
        }
     }

    est j'aimerais découper ce programme en plusieurs fonction 

    j'ai réussis a faire sa 

    void    conversion(int *cel, int *fah)
    { 
        *cel = (*fah-32) * 5 / 9;
    }
     
    int  main()
     {
       int max;
       int min;
       int inter;
       int fah;
       int cel;
    
       max = 300;
       min = 0;
       inter = 20;
    
        fah = min;
        while (fah <= max)
        {
            conversion(&cel, &fah);
            printf("%d\t%d\n", fah, cel);
            fah = fah + inter;
        }
     }
    

    Sa marche niquel mais j'essaye de le découper un une deuxième fonction est la je bloque j'ai fait sa mais sa passe pas

    void    conversion(int *cel, int *fah)
    { 
        *cel = (*fah-32) * 5 / 9;
    }
     
    void boucle(int *cel, int *fah)
    {
        int max;
        max = 300;
     
        while(fah <= max)
        {
            conversion(&cel, &fah);
        }
    }
    int  main()
     {
            int max;
            int min;
            int inter;
            int fah;
            int cel;
    
            max = 300;
            min = 0;
            inter = 20;
    
            fah = min;
            boucle(&cel,&fah);
            conversion(&cel, &fah);
            printf("%d\t%d\n", fah, cel);
            fah = fah + inter;
     }

    Si quelqu'un pourrait m'aidez merci :)

    -
    Edité par leprincefou 12 août 2019 à 4:23:51

    • Partager sur Facebook
    • Partager sur Twitter
    Notre mesure du possible rend possible l'impossible  
      12 août 2019 à 4:49:45

      Bonjour ! Houlà, tu as un souci d'organisation. En particulier la fonction 'conversion' doit être appelée par la fonction 'boucle' et non par le programme principal. Et puis tu définis des variables en dehors des fonctions, au lieu de les définir lorsqu'elles sont utiles : dans les fonctions.

      Voici comment je m'y prendrais si je devais réaliser deux fonctions similaires. J'utilise deux principes :

      1) Partir du plus global et, ensuite, détailler.

      2) Une fonction = une seule tâche. Lorsqu'on écrit une fonction, on ne doit pas se parasiter l'esprit en anticipant les autres tâches. Ce principe peut aussi s'appliquer au programme principal.

      Donc au début, on a un programme principal qui réalise une seule tâche : une boucle qui part d'une valeur minimale, s'arrête à une valeur maximal, avec un intervalle donné. Il n'y a donc besoin que de trois variables : min, max, inter.

      // Affichage des correspondances entre degrés Fahrenheit et
      // degrés Celsius, de 0°F à 300°F tous les 20°F
      int main(void)
      {
          int min = 0 ;
          int max = 300 ;
          int inter = 20 ;
          boucle(min, max, inter) ;
          return 0 ;     
      }

      Ce n'est pas au programme principal de se préoccuper de savoir comment seront convertis les degrés, donc la fonction 'conversion' n'est pas appelée ici, et les variables 'fah' et 'cel' ne sont pas déclarées ici.

      Ensuite, définissons la fonction 'boucle' :

      void boucle(int debut, int fin, int pas)
      {
          for (int fah = debut ; fah <= fin ; fah += pas)
              printf("%d F\t%d C\n", fah, celsius(fah)) ;
      }

      On voit bien que la variable 'fah' n'a pas à être définie dans le programme principale : elle ne doit appartenir qu'à la boucle.

      Remarque : j'aime bien donner des noms différents aux paramètres d'une fonction, car si on leur donne le même nom qu'à l'appel, on pourrait croire qu'il s'agit d'une même variable alors qu'il y en a réellement deux.

      Remarque : j'ai choisi une fonction de conversion qui est une « vraie fonction » et non une « procédure » : elle prend en entrée un degré Fahrenheit et retourne un degré Celsius (d'où son nom). Du coup pas besoin de pointeur. Si tu voulais t'exercer avec les pointeurs, ta fonction de conversion convient parfaitement, mais 'boucle' deviendrait :

      void boucle(int debut, int fin, int pas)
      {
          for (int fah = debut ; fah <= fin ; fah += pas)
          {
              int cel ;
              conversion(&cel, &fah) ;
              printf("%d F\t%d C\n", fah, cel) ;
          }
      }
      

      (Note que 'cel' est définie là où elle est utile.)

      Remarque : à mon avis il était inutile de mettre la boucle dans une fonction, mais j'imagine que c'est dans un but de s'exercer.

      Je n'ai pas écrit la fonction de conversion, la difficulté n'est pas là. Mais attention avec les divisions entières : 5/9 est égal à 0, pas à 0,555...

      -
      Edité par robun 12 août 2019 à 5:22:54

      • Partager sur Facebook
      • Partager sur Twitter
        12 août 2019 à 5:44:30

        Un grand merci :D j'y voie plus clair grâce a toi oui j'essaye de m'exercer avec les pointeur d'ou l'utilisation j'ai compris le principe mais j'ai encore du mal avec la pratique donc des que je peut je les utilise,

        pour la division yes il aurait fallut un float est quand suite je le récup avec le flag %f mais j'essayer juste histoire de voir si sa fonctionnait déjà comme ça 

        est oui exact c'est juste l'entrainement j'essaye de m'exercer comme je peut 

        Du coup une version du code plus améliorer donne sa ! 

        void    conversion(int *cel, int *fah)
        {
            *cel = (*fah-32) * 5 / 9;
        }
        void boucle(int debut, int fin, int pas)
        {
            int cel;
            int fah;
            fah = debut;
            while (fah <= fin)
            {
                conversion(&cel, &fah);
                printf("%d F\t%d C\n", fah, cel);
                fah = fah + pas;
            }
        }
        int main(void)
        {
            int min = 0;
            int max = 300;
            int inter = 20;
            boucle(min, max, inter);
        }

        Juste un dernier point 

        Remarque : j'ai choisi une fonction de conversion qui est une « vraie fonction » et non une « procédure » : 

        tu pourrais m'expliquer ta phrase lol il est un peu tard et j'ai du mal a comprendre je crois mais que veut tu dire par "vrai fonction" est non une "procédure" ma fonction conversion est une "procédure" ? est que veut dire l'un comme l'autre stp ?  

        -
        Edité par leprincefou 12 août 2019 à 5:51:47

        • Partager sur Facebook
        • Partager sur Twitter
        Notre mesure du possible rend possible l'impossible  
          12 août 2019 à 8:24:23

          Une « vraie » fonction retourne une valeur (y = f(x)). Quand ça ne retourne rien (« void ») on parle souvent de procédure.

          Une petite critique (mais je ne suis pas un pro du C) : je trouve maladroit de nommer ainsi les paramètres :

          void    conversion(int *cel, int *fah)

          Car 'cel' et 'fah' sont déjà pris : ce sont des entiers. Ici, dans la définition de cette fonction, 'cel' et 'fah' sont des pointeurs. Moi qui ne suis pas très à l'aise avec les pointeurs, ça m'embrouillerait. Il me semble que le nom d'une variable doit indiquer ce que c'est. Si c'est un pointeur sur une température, ça ne doit pas s'appeler de la même façon que si c'est une température. Je préférerais faire :

          void conversion(int *pcel, int *pfah)
          {
              *pcel = (*pfah-32) * 5 / 9;
          }

          où le 'p' indique que c'est un pointeur. Là, la fonction est toute simple, mais lorsque c'est plus compliqué, c'est utile de savoir qu'on a affaire à un pointeur.

          Après, encore une fois je ne suis pas pro, c'est juste un avis au passage (d'ailleurs je crois que mettre des 'p' devant tous les noms de pointeurs n'est pas forcément conseillé, mais je ne sais plus pourquoi − du coup je le fais tout le temps...)

          -
          Edité par robun 12 août 2019 à 11:12:06

          • Partager sur Facebook
          • Partager sur Twitter
            15 août 2019 à 10:04:18

            L'exemple est inutilement tarabiscoté, parce que la conversion est typiquement une  fonction qui prend une valeur  et en retourne une autre.

            float celsius(float fahr) {
               return ...;
            }


            Ce qui ne nécessite aucun pointeur.   

            Dans le Kernighan et Ritchie, duquel a été pompé cet exemple (le troisième après hello world et la conversion avec une boucle while), il y a un choix de ne parler des pointeurs que tardivement. Il faut une centaine de pages avant de rencontrer un scanf. 

            La difficulté avec les pointeurs, c'est pas de les utiliser, ce n'est pas bien difficile comme concept : une variable qui contient l'adresse d'une donnée.   & pour obtenir l'adresse d'une donnée , * pour accéder à la donnée désignée par une adresse. Coller un & ou une * ici ou là, y a pas de quoi en faire une pendule.

            Et effectivement, beaucoup de difficultés disparaissent quand on nomme  p_resultat  une variable qui contient l'adresse où il faut mettre un résultat,  au lieu de l'appeler resultat.

            Malheureusement, il y a une tradition de négligence de ce côté là (les noms des paramètres dans la doc des fonctions Unix, par exemple).

            Ne pas confondre avec la notation hongroise : ici le p dénote la signification de l'information transmise : une adresse et non une valeur. 

            Bref, la vraie difficulté, c'est de savoir quand employer les pointeurs. S'en servir pour la conversion, désolé, mais c'est s'habituer à penser de traviolle.

            -
            Edité par michelbillaud 15 août 2019 à 10:05:54

            • Partager sur Facebook
            • Partager sur Twitter
              15 août 2019 à 10:52:46

              michelbillaud a écrit:

              Ne pas confondre avec la notation hongroise : ici le p dénote la signification de l'information transmise : une adresse et non une valeur. 

              Effectivement, je pensais à la notation hongroise dont j'ai lu ici et là qu'elle était déconseillée, mais en effet le contexte est différent (elle indique le type d'une variable, alors qu'ici le 'p' sert à indiquer sa signification).
              • Partager sur Facebook
              • Partager sur Twitter
                15 août 2019 à 11:48:27

                robun a écrit:

                michelbillaud a écrit:

                Ne pas confondre avec la notation hongroise : ici le p dénote la signification de l'information transmise : une adresse et non une valeur. 

                Effectivement, je pensais à la notation hongroise dont j'ai lu ici et là qu'elle était déconseillée, mais en effet le contexte est différent (elle indique le type d'une variable, alors qu'ici le 'p' sert à indiquer sa signification).


                La notation hongroise a son intérêt quand on programme en langage d'assemblage, mais c'est complètement con quand on programme dans un langage typé, où justement les déclarations de types de variables permettent au compilateur de vérifier qu'on ne s'embrouille pas trop.

                En général, le problème du débutant avec les pointeurs en C, c'est qu'il met au hasard des * et des & parce qu'il ne sait pas bien ce que sa variable représente, et en général faute de l'avoir bien nommée.  Après viennent les erreurs d'exécution, pointeur non initialisé, fuite mémoire, double libération, usage après libération.  Mais comme le compilateur ne proteste pas, il considère que "ça marche presque".

                ---

                Un exemple de truc stupide dans les docs, getline :

                    ssize_t getline(char **lineptr, size_t *n, FILE *stream);
                

                qui fait la lecture d'une ligne dans un tampon, qui est automatiquement agrandi si nécessaire.

                A un certain niveau d'abstraction, le premier paramètre indique le tampon, le second sa capacité actuelle.

                Sauf que, dans le détail, la capacité va changer si la ligne est longue. Donc ce qu'il faut passer en réalité, c'est l'adresse de l'entier qui contient la capacité.

                Pareil pour le premier : on passe l'adresse du pointeur qui désigne le tableau contenant les caractères.

                Ca aurait été beaucoup plus clair avec un renommage

                ssize_t getline(char **p_bufferaddr, size_t *p_allocatedsize, FILE *stream);

                qui serait directement cohérent avec les explications :

                > *lineptr and *n *p_bufferaddr and *p_allocatedsize will  be  updated to reflect the buffer address and allocated size respectively.

                -
                Edité par michelbillaud 15 août 2019 à 12:04:20

                • Partager sur Facebook
                • Partager sur Twitter

                fonction est pointeur

                × 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