Pourquoi dans ce tri a bulle.... ?

Pourquoi dans ce tri a bulle.... ? - C - Programmation

Marsh Posté le 31-03-2010 à 10:16:36    

Bonjour a tous :)
 
Pourquoi dans ce code il tri correctement sauf le 1er chiffre?
 

Code :
  1. void ordonnerTableau(long tableau[], long tailleTableau);
  2. int main(int argc, char *argv[])
  3. {
  4.     long tableau[10] = {2, 4, 3, 1, 15, 6, 9, 16, 19, 12};
  5.     long i = 0;
  6.     ordonnerTableau(tableau, 10);
  7.     for(i = 0; i < 10; i++)
  8.     {
  9.         printf("%ld\n", tableau[i]);
  10.     }
  11.     return 0;
  12. }
  13. void ordonnerTableau(long tableau[], long tailleTableau)
  14. {
  15.     long i, a = 0;
  16.      for(i = 0; i < tailleTableau-1; i++)
  17.         {
  18.             if(tableau[i] > tableau[i+1])
  19.             {
  20.                 a = tableau[i+1];
  21.                 tableau[i+1] = tableau[i];
  22.                 tableau[i] = a;
  23.                 i = 0;
  24.             }
  25.         }
  26. }


 
résultat :
 
2
1
3
4
6
9
12
15
16
19

Reply

Marsh Posté le 31-03-2010 à 10:16:36   

Reply

Marsh Posté le 31-03-2010 à 10:34:24    

Quand tu permutes un élément, tu remets ensuite i à 0. Sauf que tu es dans une boucle for, et i est incrémenté automatiquement au début de chaque itération. Donc i n'est égal à 0 qu'une seule fois dans sa vie, et c'est lors de la toute première itération.

 

En règle générale, c'est une mauvaise pratique que de modifier l'itérateur d'une boucle for. Lorsque l'itérateur est amené à être modifié, il est plus propre de passer par while(), par exemple :

 
Code :
  1. long i = 0;
  2. while ( i < (tailleTableau - 1) ) {
  3.    if ( tableau[i] > tableau[i+1] ) {
  4.        // Permutation
  5.        i = 0;
  6.    }
  7.    else
  8.        ++i;
  9. }


Message édité par Elmoricq le 31-03-2010 à 10:35:37
Reply

Marsh Posté le 31-03-2010 à 11:10:04    

lassault1 a écrit :

Bonjour a tous :)

 

Pourquoi dans ce code il tri correctement sauf le 1er chiffre?

 
Code :
  1. void ordonnerTableau(long tableau[], long tailleTableau);
  2. int main(int argc, char *argv[])
  3. {
  4.     long tableau[10] = {2, 4, 3, 1, 15, 6, 9, 16, 19, 12};
  5.     long i = 0;
  6.     ordonnerTableau(tableau, 10);
  7.     for(i = 0; i < 10; i++)
  8.     {
  9.         printf("%ld\n", tableau[i]);
  10.     }
  11.     return 0;
  12. }
  13. void ordonnerTableau(long tableau[], long tailleTableau)
  14. {
  15.     long i, a = 0;
  16.      for(i = 0; i < tailleTableau-1; i++)
  17.         {
  18.             if(tableau[i] > tableau[i+1])
  19.             {
  20.                 a = tableau[i+1];
  21.                 tableau[i+1] = tableau[i];
  22.                 tableau[i] = a;
  23.                 i = 0;  // La i est remis a zero
  24.             }
  25.         } // et la i passe a 1 avant de revenir en début de boucle a cause de ton i++ en fin de boucle for
  26. }
 

résultat :

 

2
1
3
4
6
9
12
15
16
19

Comme i passe a 1 en début de nouvelle boucle, tableau[0] n'est comparé avec tableau[1] que la toute première fois que ordonnerTableau est exécutée.
Si tu remplaces ton i = 0; par i = -1; tout rentrera dans l'ordre.

 
Citation :

En règle générale, c'est une mauvaise pratique que de modifier l'itérateur d'une boucle for.

Quand on apprend a programmer oui. Quand on est un programmeur C expérimenté qui documente son code pour signaler ce type d'effet de bord sournois, non. (Bon, on serait pas en C, mais dans un vrai langage évolué avec une vrai notion d'itérateur, j'aurais une autre opinion, certes)

 

A+,

Message cité 1 fois
Message édité par gilou le 31-03-2010 à 11:14:34

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 31-03-2010 à 11:22:59    

gilou a écrit :


Citation :

En règle générale, c'est une mauvaise pratique que de modifier l'itérateur d'une boucle for.

Quand on apprend a programmer oui. Quand on est un programmeur C expérimenté qui documente son code pour signaler ce type d'effet de bord sournois, non.


 
J'ai tendance à croire que si l'on est obligé de commenter une pratique de code aussi triviale que celle-ci, c'est qu'il y a quelque chose de crade au royaume du Danemark. :o
Mais là chacun voit midi à sa porte, de toute façon j'ai bien noté "en règle générale", parce que les itérateurs ne sont pas toujours des int, et qu'il y a toujours des cas tordus qui trainent. [:dawao]

Reply

Marsh Posté le 31-03-2010 à 11:48:51    

Citation :

si l'on est obligé de commenter une pratique de code aussi triviale que celle-ci

Tu sais jamais qui fera la maintenance de ton code.
Plusieurs dizaines de millier de lignes de mon code écrites il y a une dizaine d'années sont maintenant maintenues par des programmeurs indiens sous-payé de Bangalore, alors...
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 31-03-2010 à 11:55:45    

Je n'ai pas de doute sur le fait que ceci DOIT être commenté lorsque cela se produit, et c'est justement ce qui m'ennuie (relis ma phrase ;) ).

Reply

Marsh Posté le 31-03-2010 à 11:58:35    

Merci a vous..

Reply

Marsh Posté le 31-03-2010 à 12:43:46    

Elmoricq c'est pas plutôt  i++ que ++i ?

Reply

Marsh Posté le 31-03-2010 à 12:48:58    

Elmoricq a écrit :

Je n'ai pas de doute sur le fait que ceci DOIT être commenté lorsque cela se produit, et c'est justement ce qui m'ennuie (relis ma phrase ;) ).

C'est une question d'opinion.
Je pense pour ma part que le message passé a un futur mainteneur est plus clair avec un  
for (int i=0; 0<max; i++) en une seule ligne  
qu'avec un  
int i = 0;
while (i<max)
...
++i;
sur plusieurs lignes pas successives pour certaines.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 31-03-2010 à 12:51:41    

lassault1 a écrit :

Elmoricq c'est pas plutôt  i++ que ++i ?


C'est pareil, vu que c'est une instruction indépendante ici. Sur certaines implémentations, autrefois, ++i était plus rapide dans certains cas (de nos jours, un compilo doit générer le même code sur ce type de ligne, sinon, son développeur mérite le knout).
 
Bon, je suis plus en ligne pour 24h.
A+,


Message édité par gilou le 31-03-2010 à 12:53:43

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 31-03-2010 à 12:51:41   

Reply

Marsh Posté le 31-03-2010 à 13:37:25    

gilou a écrit :

C'est une question d'opinion.


 
Clairement, on entre ici dans le domaine du "autant de pratiques que de développeurs". [:romf]

Reply

Marsh Posté le 31-03-2010 à 13:49:03    

lassault1 a écrit :

Elmoricq c'est pas plutôt  i++ que ++i ?


 
En C, quand les deux sont possibles il n'y a pas de raisons de preferer l'un a l'autre sans tomber dans de la micro-optimisation compulsive (et aleatoire, les compilateurs optimiseurs etant capables de generer le meme code).  Historiquement, i++ est plus frequent.
 
En C++, ++i retournant une référence vers i et i++ retournant un temporaire contenant l'ancienne valeur de i, il faut penser au coût de construction et de destruction de ce temporaire.  Pour les types de base, le compilateur se retrouve dans la même situation que pour le C.  Pour des iterateurs -- en particulier pour des iterateurs un peu complexe, d'une map ou d'une deque par exemple -- il pourrait avoir une différence mesurable.  Et dans du code générique, on ne sait pas a priori si on se trouve dans le cas ou c'est mesurable ou non.  L'utilisation de ++i s'est donc répandue.  Mais ceux qui ont essaye avec les conteneurs standards on eu beaucoup de mal a mesurer une différence qui ne soit pas négligeable, sans parler de le faire dans un contexte ou on fait réellement quelque chose pendant l'itération.


---------------
The truth is rarely pure and never simple (Oscar Wilde)
Reply

Marsh Posté le 31-03-2010 à 13:56:25    

Je ne savais même pas qu'il y avait (eu) une différence entre les deux syntaxes en termes de performances (je ne parle pas en terme d'interprétation dans une expression, évidemment).
 
Ici, j'ai écrit "++i" par habitude.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed