Partage
  • Partager sur Facebook
  • Partager sur Twitter

zPointers

2 Juin - 15 Juin

    2 juin 2010 à 18:12:39

    Bonjour,

    Vous pouvez proposer vos solutions ou encore demander des conseils à propos de l'exercice zPointers (2 Juin - 15 Juin).

    Bonne chance.
    • Partager sur Facebook
    • Partager sur Twitter
      2 juin 2010 à 18:32:28

      J'ai regardé les énoncés, et franchement ils m'ont l'air très intéressants ces exos, comme je les aime!

      Voici une tentative pour le premier.


      Bon bah j'ai fais le 3e aussi :-° .
      #include <stdio.h>
      #include <stdlib.h>
      
      float addition(float a, float b) { return a + b ;}
      float soustraction(float a, float b) { return a - b ;}
      float multiplication(float a, float b) { return a * b ;}
      float division(float a, float b) { return a / b ;}
      
      float (*opCode(char operateur))(float, float)
      {
          switch(operateur)
          {
              case '+' :
                  return &addition;
              case '-' :
                  return &soustraction;
              case '*' :
                  return &multiplication;
              case '/' :
                  return &division;
              default :
                  return NULL;
          }
      }
      
      float appliquer_fonction( float (*p_f)(float, float), float a, float b)
      {
          return p_f(a, b);
      }
      
      int main (void) {
      
          float (*ptr_fct)(float, float) = NULL;
          float a = 2., b = 3.;
      
          ptr_fct = opCode('+'); /* ptr_fct pointe sur la fonction addition */
          printf("%f\n", appliquer_fonction(ptr_fct, a, b));
      
          ptr_fct = opCode('-'); /* ptr_fct pointe sur la fonction soustraction */
          printf("%f\n", appliquer_fonction(ptr_fct, a, b));
      
          ptr_fct = opCode('*'); /* ptr_fct pointe sur la fonction multiplication */
          printf("%f\n", appliquer_fonction(ptr_fct, a, b));
      
          ptr_fct = opCode('/'); /* ptr_fct pointe sur la fonction division */
          printf("%f\n", appliquer_fonction(ptr_fct, a, b));
      
          return EXIT_SUCCESS;
      }
      
      • Partager sur Facebook
      • Partager sur Twitter
        2 juin 2010 à 18:59:15

        Bonjour, voilà ma solution pour tous les exercices:


        #include <stdio.h>
        #include <stdlib.h>
        
        void equilibrer_temps(size_t *semaines, size_t *jours, size_t *heures, size_t *minutes, size_t *secondes)
        {
            (*minutes) += (*secondes)/60;
            (*secondes) %= 60;
            (*heures) += (*minutes)/60;
            (*minutes) %= 60;
            (*jours) += (*heures)/24;
            (*heures) %= 24;
            (*semaines) += (*jours)/7;
            (*jours) %= 7;
        }
        
        int main()
        {
            size_t semaines, jours, heures, minutes, secondes;
        
            semaines = 0;
            jours = 8;
            heures = 20;
            minutes = 120;
            secondes = 60;
        
            equilibrer_temps (&semaines, &jours, &heures, &minutes, &secondes);
            printf("%d semaine(s), %d jour(s), %d heure(s), %d minute(s), %d seconde(s)\n", semaines, jours, heures, minutes, secondes);
            return 0;
        }
        


        #include <stdio.h>
        #include <stdlib.h>
        #include <string.h>
        
        void *my_memcpy(void * dest, const void * src, size_t n)
        {
            char *rvalue = dest;
            while (n--){
                *(char*)dest++ = *(char*)src++;
            }
            return rvalue;
        }
        
        void *my_memmove(void *dest, const void *src, size_t n)
        {
            char *temp = (char*)malloc(n*sizeof(char));
            my_memcpy(temp, src, n);
            my_memcpy(dest, temp, n);
            free(temp);
            return dest;
        }
        
        void *my_memset(void *s, int c, size_t n)
        {
            while(n--){
                *(char*)s++ = (char)c;
            }
            return s;
        }
        
        int main()
        {
            char str[] = "memmove can be very useful......";
            my_memmove (str+20,str+15,11);
            puts (str);
        
            char str1[]= "Sample string";
            char str2[40];
            char str3[40];
            my_memcpy (str2, str1, strlen(str1)+1);
            my_memcpy (str3, "copy successful", 16);
            printf ("str1: %s\nstr2: %s\nstr3: %s\n", str1, str2, str3);
        
            char str4[10];
            my_memset(str4, 'a', 10);
        
            return 0;
        }
        


        #include <stdio.h>
        #include <stdlib.h>
        
        float addition(float a, float b) { return a + b ;}
        float soustraction(float a, float b) { return a - b ;}
        float multiplication(float a, float b) { return a * b ;}
        float division(float a, float b) { return a / b ;}
        
        float (*opCode(char c)) (float, float)
        {
            float(*operation)(float, float) = NULL;
            switch(c){
                case '+':
                operation = &addition;
                break;
        
                case '-':
                operation = &soustraction;
                break;
        
                case '*':
                operation = &multiplication;
                break;
        
                case '/':
                operation = &division;
                break;
            }
            return operation;
        }
        
        float appliquer_fonction(float (*ptr)(float, float), float a, float b)
        {
            return ptr(a, b);
        }
        
        int main()
        {
            float(*op)(float, float) = opCode('*');
            printf("%f\n", appliquer_fonction(op, 2., 3.));
            return 0;
        }
        



        Edit: Fuite de mémoire dans my_memmove
        Edit2: Correction du problème de la valeur de retour de my_memcpy
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          2 juin 2010 à 19:54:51

          Je vois pas tellement les différences nécessaires (?) à l'implémentation de memmove et memcpy
          • Partager sur Facebook
          • Partager sur Twitter
            2 juin 2010 à 20:05:48

            Citation : simpsonmaniac

            Bonjour, voilà ma solution pour tous les exercices:


            La fonction my_memcpy ne retourne pas la bonne valeur.
            La fonction my_memmove a une grosse fuite de mémoire.
            • Partager sur Facebook
            • Partager sur Twitter
              2 juin 2010 à 20:07:14

              @ttthebest : Pour memcpy les zones à copier ne doivent pas se chevaucher tandis que pour memmove cela ne pose pas de problème. C'est d'ailleurs pour cela que l'on passe des pointeurs restreints à memcpy et non à memmove.
              • Partager sur Facebook
              • Partager sur Twitter
              Anonyme
                2 juin 2010 à 20:11:16

                Oui d'accord, mais dans l'implémentation elle-même je ne vois pas les différences.
                • Partager sur Facebook
                • Partager sur Twitter
                  2 juin 2010 à 20:13:35

                  Citation : Marc Mongenet

                  Citation : simpsonmaniac

                  Bonjour, voilà ma solution pour tous les exercices:


                  La fonction my_memcpy ne retourne pas la bonne valeur.
                  La fonction my_memmove a une grosse fuite de mémoire.



                  Euh, j'ai vu la fuite de mémoire mais je ne vois pas ce qui cloche pour my_memcpy :euh:
                  • Partager sur Facebook
                  • Partager sur Twitter
                    2 juin 2010 à 20:14:48

                    Il y a des précautions à prendre en plus dans le cas de memmove (vu que les zones peuvent se chevaucher) si tu ne souhaite pas avoir de surprise.

                    edit: @simpsonmaniac : tu dois renvoyer le paramètre dest non modifié, ce que tu ne fait pas.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      2 juin 2010 à 20:19:11

                      Citation : simpsonmaniac

                      Euh, j'ai vu la fuite de mémoire mais je ne vois pas ce qui cloche pour my_memcpy :euh:


                      Elle ne retourne pas la valeur de l'argument dest, car elle modifie dest dans la boucle.

                      PS: La page http://man.developpez.com/man3/memcpy.3.php est assez mal écrite, car memcpy ne renvoie pas «un pointeur sur dest», mais la valeur de dest.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        2 juin 2010 à 20:24:16

                        Ah donc memcpy renvoie l'argument dest tel qu'il lui a été passé ? C'est un peu bizarre..

                        EDIT : Ah non autant pour moi, je vois le problème. Excusez le dérangement ;)
                        • Partager sur Facebook
                        • Partager sur Twitter
                        Anonyme
                          2 juin 2010 à 22:47:58

                          Voilà je propose mon code pour l'exercice 1. Toute critique est la bienvenue ;) .
                          // zPointers
                          //	by benjamin -- June 2010
                          
                          #include <stdlib.h>
                          #include <stdio.h>
                          
                          void equilibrate_time(size_t *weeks, size_t *days, size_t *hours, size_t *minutes, size_t *seconds);
                          
                          int main(void)
                          {
                          	size_t weeks, days, hours, minutes, seconds;
                          
                          	weeks = 0;
                          	days = 8;
                          	hours = 20;
                          	minutes = 120;
                          	seconds = 60;
                          
                          	equilibrate_time(&weeks, &days, &hours, &minutes, &seconds);
                          	printf("%d weeks %d days %d hours %d minutes %d seconds\n", weeks, days, hours, minutes, seconds);
                          
                          	return EXIT_SUCCESS;
                          }
                          
                          void equilibrate_time(size_t *weeks, size_t *days, size_t *hours, size_t *minutes, size_t *seconds)
                          {
                          	*minutes += (*seconds/60);
                          	*seconds %= 60;
                          	*hours += (*minutes/60);
                          	*minutes %= 60;
                          	*days += (*hours/24);
                          	*hours %= 24;
                          	*weeks += (*days/7);
                          	*days %= 7;
                          }
                          

                          • Partager sur Facebook
                          • Partager sur Twitter
                            2 juin 2010 à 22:57:05

                            Citation : simpsonmaniac

                            Ah donc memcpy renvoie l'argument dest tel qu'il lui a été passé ? C'est un peu bizarre..


                            Oui. Je trouve aussi que c'est bizarre et inutile, mais c'est comme ça.
                            • Partager sur Facebook
                            • Partager sur Twitter
                              3 juin 2010 à 15:10:51

                              J'ai jamais essayé de coder les fonctions du deuxième exo, j'en profite aujourd'hui pour faire un essai.
                              void *_mmcpy (void* pdst, void const* psrc, register size_t size)
                              {
                                  char* dst = (char*)pdst;
                                  char const* src = (char const*)psrc;
                              
                                  for(; size--; *dst++ = *src++);
                              
                                  return pdst;
                              }
                              
                              
                              
                              void* _mmset(void *pptr, int c, register size_t size)
                              {
                                  char *ptr = (char*)pptr;
                              
                                  for(; size--; *ptr++ = (char)c);
                                  return pptr;
                              }
                              
                              
                              /*Pour le type uintptr_t, inclure <inttypes.h> */
                              void* _mmove (void *pdst, void const* psrc, register size_t size)
                              {
                                  /*
                                   Si l'adresse de destination est inférieure
                                   à l'adresse source, on copie de gauche
                                   a droite (normalement avec un memcpy)
                                   pour éviter un écrasement de données.
                                  */
                                  if((uintptr_t) pdst < (uintptr_t) psrc)
                                     return _mmcpy (pdst, psrc, size);
                                  /*
                                   Sinon on copie de droite à gauche
                                   pour éviter un écrasement.
                                  */
                                  char*       dst = (char*)pdst;
                                  char const* src = (char const*)psrc;
                              
                                  dst += (size - 1);
                                  src += (size - 1);
                                  for(; size--; *dst-- = *src--);
                              
                                  return pdst;
                              }
                              

                              J'ai pas fait beaucoup de testes, merci de me prévenir s'il y a des erreurs.
                              • Partager sur Facebook
                              • Partager sur Twitter
                                3 juin 2010 à 18:28:46

                                Citation : sercus i

                                J'ai pas fait beaucoup de testes, merci de me prévenir s'il y a des erreurs.


                                Je pense que les opérations de conversion lignes 4 et 38 auraient été plus jolies si elles respectaient la const-correctness.
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  3 juin 2010 à 22:55:28

                                  Citation : Marc

                                  Je pense que les opérations de conversion lignes 4 et 38 auraient été plus jolies si elles respectaient la const-correctness.


                                  Ok, je crois comprendre ce que tu veux dire.
                                  Merci pour ta remarque.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    8 juin 2010 à 20:58:19

                                    Je me permets de faire remonter le sujet d'exercices du mois car les exercices sont intéressants pour travailler les pointeurs et que peu de monde a participé alors que c'est une bonne occasion de s'entraîner.

                                    Je précise au passage que le type size_t pour les paramètres de l'exercice 1 a été revu car il n'était pas vraiment adapté au problème.
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      8 juin 2010 à 23:27:32

                                      Je trouve ça dommage qu'il n'y ai pas plus de participants. :(

                                      Exo 1 :

                                      void equilibrer_temps(long * sem, long * jou, long * heu, long * min, long * sec) {
                                        *min += (*sec / 60);
                                        *sec %= 60;
                                        *heu += (*min / 60);
                                        *min %= 60;
                                        *jou += (*heu / 24);
                                        *heu %= 24;
                                        *sem += (*jou / 7);
                                        *jou %= 7;
                                      }
                                      
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        9 juin 2010 à 3:49:48

                                        Citation : Pouet_forever


                                        Je trouve ça dommage qu'il n'y ai pas plus de participants. :(



                                        Tout à fait c'est dommage.
                                        Et là, ce n'est pas un problème de difficulté... :(

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Zeste de Savoir, le site qui en a dans le citron !
                                          9 juin 2010 à 10:30:13

                                          Citation : GurneyH


                                          Tout à fait c'est dommage.
                                          Et là, ce n'est pas un problème de difficulté... :(


                                          Je trouve l'exercice peu motivant. Il est trop faire du C pour faire du C à mon goût. Après, les goûts...
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            9 juin 2010 à 15:24:55

                                            Citation : Marc Mongenet

                                            Citation : GurneyH


                                            Tout à fait c'est dommage.
                                            Et là, ce n'est pas un problème de difficulté... :(


                                            Je trouve l'exercice peu motivant. Il est trop faire du C pour faire du C à mon goût. Après, les goûts...



                                            Justement c'est le but pour apprendre le C il faut faire du C pour faire du C. D'ailleurs c'est ce que beaucoup de débutants demandent pour pouvoir progresser plutôt que des exercices à visée algorithmique.
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              9 juin 2010 à 20:48:43

                                              Au fait c est quoi la différence entre un exo
                                              "faire du c pour le c"
                                              et un exo d' algoritmique?
                                              Merci
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                9 juin 2010 à 21:13:34

                                                Un exercice d'algorithmique pose un problème que l'on doit résoudre grâce à une suite d'opérations effectuées un ordre précis, de plus ce problème ne dépend pas d'un langage en particulier. Par exemple dans l'exercice 1 de ce mois ci qui a pour but "d'équilibrer" le temps il y a une démarche a respecter pour obtenir le résultat final, cette démarche peut être transcrite dans n'importe quel langage à partir de l'algorithme.

                                                Tandis que faire du C pour faire du C demande uniquement des connaissances en C et seulement en C. Rien de plus.
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  10 juin 2010 à 16:12:30

                                                  bonjour,

                                                  Une participation pour l'exercice 3
                                                  #include <stdio.h>
                                                  #include <stdlib.h>
                                                  
                                                  /* Exercice 3 */
                                                  double addition(double a, double b) { return a + b ;}
                                                  double soustraction(double a, double b) { return a - b ;}
                                                  double multiplication(double a, double b) { return a * b ;}
                                                  double division(double a, double b) { return a / b ;}
                                                  
                                                  double (*getOp(int op))(double, double)
                                                  {
                                                      size_t i;
                                                      struct action
                                                      {
                                                          char const op;
                                                          double(*f)(double, double );
                                                      };
                                                  
                                                      static struct action actions[] =
                                                      {
                                                          {'+', addition},
                                                          {'-', soustraction},
                                                          {'*', multiplication},
                                                          {'/', division}
                                                      };
                                                  
                                                      for(i = 0; i < sizeof actions / sizeof *actions; i++)
                                                          if(op == actions[i].op)
                                                              return actions[i].f;
                                                  
                                                      return NULL;
                                                  }
                                                  
                                                  
                                                  double doOp(double a, double b, int op)
                                                  {
                                                      double(*f)(double, double) = getOp(op);
                                                      if(f == NULL)
                                                      {
                                                          fprintf(stderr, "opcode inconnu :%c\n", op);
                                                          exit(EXIT_FAILURE);
                                                  
                                                      }
                                                      return f(a, b);
                                                  }
                                                  
                                                  int main (void)
                                                  {
                                                      printf("%f\n", doOp(5.0, 3.0, '+'));
                                                      printf("%f\n", doOp(5.0, 3.0, '-'));
                                                      printf("%f\n", doOp(5.0, 3.0, '*'));
                                                      printf("%f\n", doOp(5.0, 3.0, '/'));
                                                      printf("%f\n", doOp(5.0, 3.0, 'a'));
                                                  
                                                      return EXIT_SUCCESS;
                                                  }
                                                  
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  Zeste de Savoir, le site qui en a dans le citron !
                                                    11 juin 2010 à 4:48:18

                                                    Vu qu'on manque de participants par ici, j'apporte ma petite touche perso (histoire de vous faire bouger un peu :D ).
                                                    void *memmove(void *dest, const void *src, size_t n)
                                                    {
                                                    	__asm__ __volatile__ ("movl %0, %%esi\n\
                                                    \tmovl %1, %%edi\n\
                                                    \tcld\n\
                                                    \tmovl %2, %%ecx\n\
                                                    \trep movsl"
                                                    			      :
                                                    			      :"r"(src), "r"(dest), "r"(n)
                                                    			      :"%eax");
                                                    	return dest;
                                                    }
                                                    


                                                    haha, longue vie à l'assembleur, l'un des rares langages qui permet de faire des boucles sans faire de boucles (jeu de mot :) ).
                                                    Et puis je l'ai intégré dans le C comme ça on ne me dit pas que c'est pas du C.
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      11 juin 2010 à 4:56:45

                                                      :p
                                                      ça compile sans warnings.

                                                      edit:
                                                      mais
                                                      #include <stdio.h>
                                                      #include <string.h>
                                                      void *arthurus_memmove(void *dest, const void *src, size_t n)
                                                      {
                                                          __asm__ __volatile__ ("movl %0, %%esi\n\
                                                      \tmovl %1, %%edi\n\
                                                      \tcld\n\
                                                      \tmovl %2, %%ecx\n\
                                                      \trep movsl"
                                                                            :
                                                                            :"r"(src), "r"(dest), "r"(n)
                                                                                    :"%eax");
                                                          return dest;
                                                      }
                                                      
                                                      int main(void)
                                                      {
                                                          char tab1[] = "abcdefghijklmno";
                                                          char tab2[] = "abcdefghijklmno";
                                                      
                                                          printf ("tab1 = %s\n", tab1);
                                                          arthurus_memmove (tab1 + 5, tab1 + 2, 7);
                                                          printf ("tab1 = %s\n\n", tab1);
                                                      
                                                      
                                                          printf ("tab2 = %s\n", tab2);
                                                          memmove (tab2 + 5, tab2 + 2, 7);
                                                          printf ("tab2 = %s\n\n", tab2);
                                                      
                                                          return 0;
                                                      }
                                                      

                                                      tab1 = abcdefghijklmno
                                                      tab1 = abcdecdefdefjefjnfjn↨jn↨Pn↨P
                                                      
                                                      tab2 = abcdefghijklmno
                                                      tab2 = abcdecdefghimno
                                                      
                                                      
                                                      Process returned 0 (0x0)   execution time : 0.313 s
                                                      Press any key to continue.

                                                      niark niark.
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                      Zeste de Savoir, le site qui en a dans le citron !
                                                        11 juin 2010 à 5:03:37

                                                        haha, je ne sais pas si cette syntaxe passe dans un autre compilateur que gcc (ça m'étonnerait).

                                                        EDIT :
                                                        lol, tant pis alors ! ça gère pas les straddles... Trop la flemme de le faire en __asm__, donc je ne le fais pas :D
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                          14 juin 2010 à 13:37:44

                                                          On va dire que je réagis un peu tard mais pas grave :

                                                          Citation : sercus i


                                                          Dans la fonction _mmove à la ligne 31 tu compare deux pointeurs or d'après la norme le comportement n'est pas toujours défini.

                                                          Citation : n1124 : 6.5.8 §5

                                                          When two pointers are compared, the result depends on the relative locations in the
                                                          address space of the objects pointed to. If two pointers to object or incomplete types both
                                                          point to the same object, or both point one past the last element of the same array object,
                                                          they compare equal. If the objects pointed to are members of the same aggregate object,
                                                          pointers to structure members declared later compare greater than pointers to members
                                                          declared earlier in the structure, and pointers to array elements with larger subscript
                                                          values compare greater than pointers to elements of the same array with lower subscript
                                                          values. All pointers to members of the same union object compare equal. If the
                                                          expression P points to an element of an array object and the expression Q points to the
                                                          last element of the same array object, the pointer expression Q+1 compares greater than
                                                          P. In all other cases, the behavior is undefined.



                                                          Solution possible : Tu copie de droite à gauche dans tous les cas.
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            14 juin 2010 à 14:39:30

                                                            Citation : Lithrein

                                                            Solution possible : Tu copie de droite à gauche dans tous les cas.


                                                            Euh non, il me semble que si l'on s'interdit la comparaison des adresses source et destination, la seule solution restante pour implémenter memmove passe par un tableau temporaire.
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              14 juin 2010 à 14:48:00

                                                              Citation : Marc Mongenet

                                                              Citation : Lithrein

                                                              Solution possible : Tu copie de droite à gauche dans tous les cas.


                                                              Euh non, il me semble que si l'on s'interdit la comparaison des adresses source et destination, la seule solution restante pour implémenter memmove passe par un tableau temporaire.


                                                              Tu es sur que l'on ne peut pas. Il ne me semble pas que l'on soit obligé de faire de comparaisons d'adresses si on copie en arrière.
                                                              void *
                                                              _memmove (void * dest, const void * src, size_t n) {
                                                                  char * _dest = (char *)dest + n;
                                                                  const char * _src = (char *)src + n;
                                                              
                                                                  while (n--)
                                                                      *--_dest = *--_src;
                                                              
                                                                  return dest;
                                                              }
                                                              
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              zPointers

                                                              × 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