Partage
  • Partager sur Facebook
  • Partager sur Twitter

[tutos] Exo tableau

une fonction qui ne va pas au bout

    14 juin 2006 à 2:46:36

    Bonsoir! ^^

    voila, je suis à l'exercice sur le tri d'un tableau.
    Au bout de plus de 3h de gribouillage et codage, je suis arrivé à une fonction
    qui part bien, mais ne fini pas son boulot. Je vous montre tous ça:
    #include <cstdlib>
    #include <iostream>

    using namespace std;
    long trier (long *tableau, long taille);
    int main(int argc, char *argv[])
    {
        long tableau[5]={15,81,21,13};
        printf("avant:\n");
        long i;
        for (i=0; i<5; i++)
        {
            printf(" %i ", tableau[i]);
        }
        printf("\n\n pendant \n");
        trier(tableau, 5);
        printf("\napres:\n");
        for (i=0; i<5; i++)
        {
            printf(" %i ", tableau[i]);
        }
        printf("\n\n");
        system("PAUSE");
        return EXIT_SUCCESS;
    }

    long trier (long *tableau, long taille)
    {
         long i=0,j=0;
         long temp;
         for (i=0; i<taille-1; i++)
         {
             for (j=i+1; j<taille-i; j++)
             {
                 if (tableau[j]<tableau[i])
                 {
                    temp=tableau[i];
                    *(tableau+i)=tableau[j];
                    *(tableau+j)=temp;

                    //cette partie ne sert qu'a afficher les etapes intermediaires:
                    long x;
                    printf("i:%i, j:%i  ",i,j);
                    for (x=0; x<5; x++)
                     {
                       printf(" %i ", tableau[x]);
                     }
                     printf("\n");
                 }
                 
             }
             
         }
     }

    Le résultat:

    avant:
    15 81 21 13 0

    pendant
    i=0, j=3 13 81 21 15 0
    i=0, j=4 0 81 21 15 13
    i=1, j=2 0 21 81 15 13
    i=1, j=3 0 15 81 21 13

    apres:
    0 15 81 21 13


    j'ai refais plusieurs fois le programme à la main, je ne comprend pas pourquoi il s'arrette en plein milieu :o ... une idée?

    • Partager sur Facebook
    • Partager sur Twitter
      14 juin 2006 à 6:42:08

      C'est pas plutôt du C++ ça?

      Citation : Code C?

      #include <cstdlib>
      #include <iostream>

      using namespace std;



      Aussi, t'as aucun return dans ta fonction trier, donc tu devrait mettre void au lieu de long.

      Ensuite, tu te compliques un peu la vie avec tes *(tableau+i) = tableau[j]
      -->

      Citation : Cours de Matheo, chapitre sur les tableaux

      //Les 2 lignes suivantes sont donc identiques :

      Code : C
      tableau[1] // Renvoie la valeur contenue dans la seconde case (la première case étant 0)
      *(tableau + 1) // Identique : renvoie la valeur contenue dans la seconde case


      Tu pourrais tout betement mettre tableau[1].

      Et finalement, la solution au probleme:
      la boucle avec les j, met for(j=i+1; j<taille-i; j++)
      parce que la, rendu a i = 2, ta boucle ressemble a : for(j=3; j<3; j++)
      ta boule ne s'effectuera jamais ;)
      for (i=0; i<taille-1; i++)
           {
               for (j=i+1; j<taille; j++)
               {
                   if (tableau[j]<tableau[i])
                   {
                      temp=tableau[i];
                      *(tableau+i)=tableau[j];
                      *(tableau+j)=temp;

                     
                       printf("\n");
                   }
                   
               }
               
           }


      Voila
      Fred :)

      PS: Avec ce code (et le 5 remplacé par 8) :
      Image utilisateur
      • Partager sur Facebook
      • Partager sur Twitter
        14 juin 2006 à 10:53:27

        Citation :

        C'est pas plutôt du C++ ça?


        exact, dans Dev-C++ c'est l'option par défaut j'ai pas trop fait attention.

        Citation :

        Aussi, t'as aucun return dans ta fonction trier, donc tu devrait mettre void au lieu de long.


        que d'inattention hier soir, c'est en effet plus pertinent ^^


        for (i=0; i<taille-1; i++)
             {
                 for (j=i+1; j<taille; j++)
                 {
                     if (tableau[j]<tableau[i])
                     {
                        temp=tableau[i];
                        tableau[i]=tableau[j];
                        tableau[j]=temp;

                       
                         printf("\n");
                     }
                     
                 }
                 
             }

        Pour la boucle J, je suis partis dans une logique
        qui finalement ne l'était pas :p (taille-i devait représenter le nombre de cases du tableaux qui sont "à la droite" de tableaux[i], c'est le cas mais on s'en fiche un peu finalement)
        Donc comme ça, plus logiquement, ça fonctionne ^^

        Merçi Fred! :)
        • Partager sur Facebook
        • Partager sur Twitter
          14 juin 2006 à 11:09:23

          Citation : freecircus

          voila, je suis à l'exercice sur le tri d'un tableau.
          Au bout de plus de 3h de gribouillage et codage, je suis arrivé à une fonction
          qui part bien, mais ne fini pas son boulot. Je vous montre tous ça:
          <...>
          j'ai refais plusieurs fois le programme à la main, je ne comprend pas pourquoi il s'arrette en plein milieu :o ... une idée?


          Les limites des boucles sont fantaisistes...

          Correction (en C)

          #define DBG 0
          #include <stdio.h>
          #include <stdlib.h>

          static long trier (long *tableau, long taille)
          {
             long i;
             for (i = 0; i < taille; i++)
             {
                long j;
                for (j = i; j < taille; j++)
                {
                   if (tableau[j] < tableau[i])
                   {
                      long temp = tableau[i];
                      tableau[i] = tableau[j];
                      tableau[j] = temp;
          #if DBG

                      printf("i:%i, j:%i  ", i, j);
                      {
                         long x;
                         for (x = 0; x < 5; x++)
                         {
                            printf(" %i ", tableau[x]);
                         }
                      }
                      printf("\n");
          #endif
                   }
                }
             }
          }


          static long afficher (long const *tableau, long taille)
          {
             long i;
             for (i = 0; i < taille; i++)
             {
                printf(" %i ", tableau[i]);
             }
             printf ("\n");
          }

          int main()
          {
             long tableau[] = {
                                  15, 81, -1, 21, 13, -3
                                  };
             afficher(tableau, sizeof tableau / sizeof *tableau);
             trier(tableau, sizeof tableau / sizeof *tableau);
             afficher(tableau, sizeof tableau / sizeof *tableau);

             return EXIT_SUCCESS;
          }


          15 81 -1 21 13 -3
          -3 -1 13 15 21 81

          Press ENTER to continue.

          Pose des questions si tu ne comprends pas.
          • Partager sur Facebook
          • Partager sur Twitter
          Music only !
            14 juin 2006 à 15:09:37

            Pour les boucles, j'ai compris le principe, ça marche ^^

            Au sujet de ton code j'ai en effet 2 questions:
            -au sujet de la fonction sizeof: J'ai lu qu'elle renvoi la taille en octet de la mémoire occupé par l' "objet"(ça ne doit pas être le bon termes) placé en paramètre.
            j'ai fais un petit test pour essayer de comprendre:


            #include <stdio.h>
            #include <stdlib.h>

            int main(int argc, char *argv[])
            {
                long tableau[14]={15,23,97,45,-6,0,15};
                printf("sizeof tableau: %i\nsizeof *tableau: %i\nsizeof tableau/ sizeof *tableau: %i\n", sizeof tableau, sizeof *tableau, sizeof tableau/sizeof *tableau);
             
              system("PAUSE");     
              return 0;
            }

            resultat:
            sizeof tableau: 56
            sizeof *tableau: 4
            sizeof tableau/ sizeof *tableau: 14

            on retrouve bien la taille du tableau, mais pour l'instant j'ai l'impréssion que ça relève de la magie :D
            que renvoie donc concrètement sizeof tableau et sizeof *tableau?
            tableau étant en principe l'adresse de la première case et *tableau sa valeur..

            -2ème question au sujet du #define et de la condition:
            #if DBG

                        printf("i:%i, j:%i  ", i, j);
                        {
                           long x;
                           for (x = 0; x < 5; x++)
                           {
                              printf(" %i ", tableau[x]);
                           }
                        }
                        printf("\n");
            #endif

            j'ai appris dans les tutos que le code est compilé en fonction de si la condition est remplie ou non, mais quel est son rôle ici? qu'apporte t elle de plus?
            également, pourquoi il y a t il des accolades après le premier printf?

            merçi de ce complément ^^
            • Partager sur Facebook
            • Partager sur Twitter
              14 juin 2006 à 16:07:56

              Citation : freecircus


              Au sujet de ton code j'ai en effet 2 questions:
              -au sujet de la fonction sizeof: J'ai lu qu'elle renvoi la taille en octet de la mémoire occupé par l' "objet"(ça ne doit pas être le bon termes) placé en paramètre.


              Oui, comme indiqué dans ton livre de C. sizeof est un opérateur unaire qui retourne la taille d'un objet en bytes (son opérande). Le type retourné est size_t.

              Citation : Pas de titre


              j'ai fais un petit test pour essayer de comprendre:


              Très bonne initative. Un peu d'expérimentation permet de 'fixer' les idées...

              Citation : Pas de titre


              #include <stdio.h>
              #include <stdlib.h>

              int main(int argc, char *argv[])
              {
                  long tableau[14]={15,23,97,45,-6,0,15};
                  printf("sizeof tableau: %i\n"
                         "sizeof *tableau: %i\n"
                         "sizeof tableau / sizeof *tableau: %i\n"
                         , sizeof tableau
                         , sizeof *tableau
                         , sizeof tableau/sizeof *tableau);
               
                system("PAUSE");     
                return 0;
              }


              resultat:

              sizeof tableau: 56
              sizeof *tableau: 4
              sizeof tableau/ sizeof *tableau: 14



              Ca fonctionne un peu par hasard, parce que les types et les formatteurs ne concordent pas, mais le résultat est néanmois correct (mais pas le comportement).

              Citation : Pas de titre


              on retrouve bien la taille du tableau, mais pour l'instant j'ai l'impréssion que ça relève de la magie :D
              que renvoie donc concrètement sizeof tableau et sizeof *tableau?
              tableau étant en principe l'adresse de la première case et *tableau sa valeur..


              • sizeof tab retourne la taille du tableau en mémoire en nombre de bytes.
              • sizeof *tab (idem sizeof tab[0]) retourne la taille du premier élément du tableau en mémoire en nombre de bytes.
              • Un tableau étant une séquence d'objets identique, pas besoin de te faire un dessin sur le sens de sizeof tab / sizeof *tab...

              Ce mécanisme fonctionne toujours avec un tableau (j'insiste sur tableau)...

              Citation : Pas de titre


              -2ème question au sujet du #define et de la condition:

              #if DBG

                          printf("i:%i, j:%i  ", i, j);
                          {
                             long x;
                             for (x = 0; x < 5; x++)
                             {
                                printf(" %i ", tableau[x]);
                             }
                          }
                          printf("\n");
              #endif


              j'ai appris dans les tutos que le code est compilé en fonction de si la condition est remplie ou non, mais quel est son rôle ici? qu'apporte t elle de plus?


              C'est du code de mise au point (debug). Je préfère l'isoler (ne pas le compiler) quand je n'en ai plus besoin. Mais il est toujours là et peut être réactivé rapidement en jouant sur la valeur de la macro DBG (0=normal 1=debug)

              Citation : Pas de titre


              également, pourquoi il y a t il des accolades après le premier printf?


              Pour pouvoir définir la variable locale x.

              Rappel : En C90, les variables locales doivent être définies au début d'un bloc.
              • Partager sur Facebook
              • Partager sur Twitter
              Music only !
                14 juin 2006 à 16:57:04

                Citation :

                • sizeof tab retourne la taille du tableau en mémoire en nombre de bytes.
                • sizeof *tab (idem sizeof tab[0]) retourne la taille du premier élément du tableau en mémoire en nombre de bytes.
                • Un tableau étant une séquence d'objets identique, pas besoin de te faire un dessin sur le sens de sizeof tab / sizeof *tab...


                Ce mécanisme fonctionne toujours avec un tableau (j'insiste sur tableau)...


                d'accord, une petite subtilité qui peut se révéler bien utile ça ^^

                Citation :

                C'est du code de mise au point (debug). Je préfère l'isoler (ne pas le compiler) quand je n'en ai plus besoin. Mais il est toujours là et peut être réactivé rapidement en jouant sur la valeur de la macro DBG (0=normal 1=debug)


                une façon de faire qui doit bien faciliter le travail, à retenir ^^

                Citation :

                Citation :

                également, pourquoi il y a t il des accolades après le premier printf?

                Pour pouvoir définir la variable locale x.
                Rappel : En C90, les variables locales doivent être définies au début d'un bloc.


                ok, je n'ai vu nul part encore qu'on peut utiliser les accolades pour définire autre chose que des fonctions ou boucles. j'ai fait quelques test encore, j'vois l'concept.

                merçi de toute ces précision -ed-!
                ça m'as fait beaucoup avancé ^^

                une dernière question pour la route :D au sujet du test sur sizeof:

                Citation :

                Ca fonctionne un peu par hasard, parce que les types et les formateurs ne concordent pas, mais le résultat est néanmois correct (mais pas le comportement).


                j'ai mis longtemps à trouver ce que sont les formateurs, dans les tutos de M@theo c'est un "symbole spécial" :D on a pas plus de précision (enfin la ou j'en suis).
                donc.. si le type renvoyé par sizeof est size_t, c'est quand même un entier, pourquoi un simple %i ne pourrait-il pas sufir? que mettre à la place?
                • Partager sur Facebook
                • Partager sur Twitter
                  14 juin 2006 à 20:55:31

                  Citation : freecircus

                  une dernière question pour la route :D au sujet du test sur sizeof:

                  Citation :

                  Ca fonctionne un peu par hasard, parce que les types et les formateurs ne concordent pas, mais le résultat est néanmois correct (mais pas le comportement).


                  j'ai mis longtemps à trouver ce que sont les formateurs, dans les tutos de M@theo c'est un "symbole spécial" :D on a pas plus de précision (enfin la ou j'en suis).
                  donc.. si le type renvoyé par sizeof est size_t, c'est quand même un entier, pourquoi un simple %i ne pourrait-il pas sufir? que mettre à la place?


                  Parce 'un entier', c'est vague. Le C dit que size_t est un entier non signé mais ne donne pas d'indication sur son type. On est donc embété pour trouver le bon formatteur.

                  En C90, Il existe néanmoins une possibilité portable qui est de choisir le plus grand formatteur possible entier non signe ("%lu") et le cast associé (unsigned long). On est alors sûr du fonctionnement :
                    printf ("sizeof tab = %lu\n", (unsigned long) sizeof tab);

                  En C99, il existe un formatteur spécial qui évite ces bidouilles : "%zu" :
                    printf ("sizeof tab = %zu\n", sizeof tab);

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Music only !

                  [tutos] Exo tableau

                  × 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