if ou do while ou while??
Répondre à la discussion
Affichage des résultats 1 à 20 sur 20

if ou do while ou while??



  1. #1
    invite8b421ec7

    Unhappy if ou do while ou while??


    ------

    Bonjour,

    Je sais que ce problème est bête mais je ne comprends pas.
    Voilà, je souhaiterais écrire un programme qui permet de chercher l'élément attaché (distance plus faible) à un élément déterminé dans un ensemble d'éléments. Quand l'élément trouvé n'est pas visité on regarde s'il correspond à la condition
    Code:
     if(chargeProduit1>=0&&chargeProduit2>=0&&capaciteRestante>=0)
    (voir mon programme ci-dessous). S'il c'est le cas on prend cet élément. Sinon, on regarde l'élément le plus loin.
    Ci-dessous mon programme. La valeur de l'élément trouvé correspond aux conditions est stockée dans la variable noeudProche .
    Lors de l'exécution de mon programme, le compilateur m'affiche le même contenu de la variable noeudProche comme si il n'a pas tenu compte de cette ligne
    Code:
     if(chargeProduit1>=0&&chargeProduit2>=0&&capaciteRestante>=0)
    .

    Pourquoi
    Faut-il utiliser do while ou while au lieu de if pour que quand il ne trouve pas que la valeur de la variable chargeProduit1 et la valeur de la variable chargeProduit2sont >=0, il va chercher un autre élément (noeudProche) plus loin qui satisfait ces dernières conditions?
    Merci par avance de vos aides.
    Code:
    int chercherNoeud(int nbreNoeudsTrouve, double **distanceEntreVertices,  GestionNoeuds *pGestionNoeuds, Circuit *pCircuit, int noeudDebut)
    {
        int i,j;
    
        int trouve;
        int noeudProche = 0;
        double distanceMin =1000;
        int chargeProduit1 =0;
        int chargeProduit2 =0;
        int capaciteRestante = capaciteMax;
    
        for(i=0;i<nbreNoeuds;i++)
        {
    
               trouve =0;//trouve est faux
    
    
                   j=0;
                   while(trouve==0&&j<taille)
                   {
    
                         if(i==pCircuit->tableau[j])
                         {
                              trouve = 1;
    
    
                        }
                        else
                        {
    
                             j++;
                        }
    
                   }
                   if(trouve==0 && distanceMin>distanceEntreVertices[noeudDebut][i])
                   {
                     distanceMin=distanceEntreVertices[noeudDebut][i];
                     noeudProche = i;
                     chargeProduit1 += pGestionNoeuds->tableau[noeudProche].demandProduit1;
                     chargeProduit2+= pGestionNoeuds->tableau[noeudProche].demandProduit2;
                     capaciteRestante-=pGestionNoeuds->tableau[noeudProche].demandProduit1 + pGestionNoeuds->tableau[ noeudProche].demandProduit2;
                     if(chargeProduit1>=0&&chargeProduit2>=0&&capaciteRestante>=0)
                     {
                          noeudProche = i;
                     }
    
    
                   }
        }
    
         return noeudProche;
    }

    -----

  2. #2
    Dlzlogic

    Re : if ou do while ou while??

    Bonjour,
    J'ai recopié votre code en supprimant les lignes blanches, des accolages inutiles et surtout en remplaçant while par for

    Code:
    int chercherNoeud(int nbreNoeudsTrouve, 
                                double **distanceEntreVertices,  
                                GestionNoeuds *pGestionNoeuds, 
                                Circuit *pCircuit, int noeudDebut)
    {
    
        int trouve;
        int noeudProche = 0;
        double distanceMin =1000;
        int chargeProduit1 =0;
        int chargeProduit2 =0;
        int capaciteRestante = capaciteMax;
    
        for(int i=0; i<nbreNoeuds; i++)
        {
            trouve =0;//trouve est faux
    //               j=0;
    //               while(trouve==0&&j<taille)
                    for (int j=0; j< taille; j++)
                   {
                         if(i == pCircuit->tableau[j])
                         {
                              trouve = 1;
                              break;  // pas la peine d'aller chercher plus loin
                        }
    
                   }
                   if(trouve==0 &&        
                       distanceMin > distanceEntreVertices[noeudDebut][i])
                   {
                      distanceMin=distanceEntreVertices[noeudDebut][i];
                      noeudProche = i;
                      chargeProduit1 += pGestionNoeuds->tableau[noeudProche].demandProduit1;
                      chargeProduit2+= pGestionNoeuds->tableau[noeudProche].demandProduit2;
                     capaciteRestante-=pGestionNoeuds->tableau[noeudProche].demandProduit1 + pGestionNoeuds->tableau[ noeudProche].demandProduit2;
                      if(chargeProduit1 >= 0 && chargeProduit2 >= 0 && capaciteRestante >= 0)
                     {
                          noeudProche = i;
                     }
                   }  // fin de la séquence trouve == 1
    /* si on ne l'a pas trouve, que se passe-t-il ?
    Est-ce une erreur, en c cas il faut une impression 
    */
        }
    // ce sera toujours le dernier i valable trouvé
         return noeudProche;
    }
    Ca ce n'est qu'une première réponse. Maintenant, je vais essayer de comprendre quel est le rang que vous essayez de récupérer.
    Je n'ai pas vu la déclaration de "taille"

  3. #3
    Dlzlogic

    Re : if ou do while ou while??

    Suite,
    Vous faites dans tous les cas, si trouve == 1,
    NoeudProche = i;
    Donc la valeur renvoyée sera toujours la dernière valeur de i, c'est à dire en général nbreNoeuds.

  4. #4
    invite8b421ec7

    Re : if ou do while ou while??

    Merci Dlzlogic de votre réponse.
    Citation Envoyé par Dlzlogic Voir le message
    Je n'ai pas vu la déclaration de "taille"
    En fait taille du tableau est fixe (#define taille ).
    Citation Envoyé par Dlzlogic Voir le message
    si on ne l'a pas trouve, que se passe-t-il ?
    C'est à dire que l'élément est déjà pris.
    Sinon, l'élément i valable est celui qui respecte cette condition
    Code:
    if(chargeProduit1>=0&&chargeProduit2>=0&&capaciteRestante>=0)
    Si ce ne l'est pas le cas, on cherche un autre élément parmi les éléments trouvés.
    Merci encore de votre aide.

  5. A voir en vidéo sur Futura
  6. #5
    whoami

    Re : if ou do while ou while??

    Bonjour,

    Quoi qu'il en soit, une bonne habitude à prendre est d'écrire du code clair, ce qui implique qu'il doit être lisible sans se crever les yeux.

    Exemple typique dans ton code:
    Code:
    if(chargeProduit1>=0&&chargeProduit2>=0&&capaciteRestante>=0)
    qui devient nettement plus lisible si on aère un peu :
    Code:
    if (chargeProduit1 >=0 && chargeProduit2 >=0 && capaciteRestante >= 0)
    et encore mieux si on rend plus visible encore en ajoutant des parenthèses, pour éviter d'avoir à réfléchir sur la priorité des opérateurs (ici, ça ne joue pas trop, mais parfois, pour éviter quelques parenthèses, l'auteur même finit par ne plus s'y retrouver, et doit reprendre son code en faisant ce qu'il faut).
    Code:
    if ( (chargeProduit1 >=0) && (chargeProduit2 >=0) && (capaciteRestante >= 0) )

  7. #6
    invite8b421ec7

    Unhappy Re : if ou do while ou while??

    Re,

    Voici la dernière version de ma fonction. Je n'obtiens toujours pas le bon résultat .
    Code:
    int chercherNoeudPlusProche(int nbreNoeudsTrouve, double **distanceEntreVertices,  GestionNoeuds *pGestionNoeuds, Circuit *pCircuit, int noeudDebut)
    {
        int i,j,b;
        int trouve;
        int noeudProche = 0;
        double distanceMin =1000;
        int chargeProduit1 =0;
        int chargeProduit2 =0;
        int capaciteRestante = capaciteMax;
        for(i=0; i < nbreNoeuds ; i++)
        {
             trouve =0;//trouve est faux
             j=0;
    
             while(trouve == 0 && j < taille)
              {
                   if(i == pCircuit->tableau[j])
                   {
                        trouve = 1;
                   }
                   else
                   {
                        j++;
                   }
    
              }
              b=0;
              //si l'element n est pas encore visité
              if(trouve == 0 && distanceMin > distanceEntreVertices[noeudDebut][i])
              {
                   distanceMin = distanceEntreVertices[noeudDebut][i];
                   noeudProche =  i;// l element le plus proche
                   chargeProduit1 += pGestionNoeuds->tableau[noeudProche].demandProduit1;
                   printf("\nchargeP1 %d\n",chargeProduit1);
                   chargeProduit2 += pGestionNoeuds->tableau[noeudProche].demandProduit2;
                   printf("\nchargeP2 %d\n",chargeProduit2);
                   //on fait le test. Si c'est le cas, on recherche un autre
                   while((chargeProduit1<= 0) && (chargeProduit2 <= 0))
                   {
                        //chercher un autre element plus loin
                        b++;
                   }
              }
         }
         return noeudProche;
    }
    Voici ce que je cherche à faire
    • chercher l'élément attaché (distance plus faible) à un élément déterminé dans un ensemble d'éléments.
    • Quand l'élément trouvé n'est pas visité on regarde s'il correspond à la condition
      Code:
      if((chargeProduit1 >= 0) && (chargeProduit2 >= 0))
      S'il c'est le cas on prend cet élément. Sinon, on regarde l'élément le plus loin

  8. #7
    Dlzlogic

    Re : if ou do while ou while??

    Bon, la logique pour chercher le noeud le plus proche d'un point donné peut être écrite ainsi
    typedef struct TABLEAU
    {
    int ChargeProduit1;
    int ChargeProduit2;
    double X;
    double Y;
    } Tab;
    typedef Tab *Tableau;
    // là, on crée les pointeurs
    // puis on les initialise.
    Code:
    int ChercheProche(struct TABLEAU *Tableau, 
                                int nbNoeuds, double Xp, double Yp)  
    {
      double DistMin= 1.e50;  // très grand nombre
      int rang = -1;
      for (int i=0; i < nbNoeuds; i++)
      {
         if ( Tableau[i]->ChargeProduit1 != 0 && Tableau[i]->ChargeProduit2 != 0)
         double Dist=Distance(Xp, Yp, Tableau[i]->X, Tableau[i]->Y);
         if (Dist <  DistMin )
         {
            rang = i;
            DistMin = Dist;
         }
      } 
       return rang;
    }
    Cette fonction doit être appelée pour chaque point à étudier. Donc sera appelée dans une boucle for.
    Vous remarquerez que je fais le test de la condition avant le calcul de distance.
    Je veux bien debuger votre programme, mais il me faudrait la totalité du code. Si vous voulez faire comme ça il vaut mieux me le mettre en pièce jointe dans un mail.
    N'ayez aucun souci, je suis très disponible.

  9. #8
    bzh_nicolas

    Re : if ou do while ou while??

    Citation Envoyé par Dlzlogic Voir le message
    Bonjour,
    J'ai recopié votre code en supprimant les lignes blanches, des accolages inutiles et surtout en remplaçant while par for

    Code:
         for (int j=0; j< taille; j++)
                   {
                         if(i == pCircuit->tableau[j])
                         {
                              trouve = 1;
                              break;  // pas la peine d'aller chercher plus loin
                        }
    
                   }
    C'est pas terrible ce genre de code, les breaks sont efficaces et fonctionnent bien mais sont de mauvaises habitudes de programmation. S'ils se retrouvent en nombres dans un programmes, ils peuvent rapidement rendre du code illisible et difficile à déboguer.
    Les instructions break étaient surtout utiles lorsque l'on devait optimiser à fond un programme en économisant au maximum la mémoire et l'utilisation du processeur, ce n'est plus le cas aujourd'hui.
    J'ajouterai que ce n'est pas du tout formateur pour quelqu'un qui débute en programmation.

    @Celine2 :
    Je suis plus ou moins tes différends posts depuis le début, j'ai remarqué que tu es débutante mais je dois bien reconnaitre que tu as plus de faiblesses en algorithmiques que je ne le pensais. Alors même conseil que d'habitude : PAPIER-CRAYON.

    J'ajouterais que tu dois revoir sérieusement les bases, un if (c'est à dire une condition) n'est pas du tout la même chose qu'un boucle.
    TU as fait cette modification :
    Code:
    while((chargeProduit1<= 0) && (chargeProduit2 <= 0))
                   {
                        //chercher un autre element plus loin
                        b++;
                   }
    Prends un papier et un crayon et dis moi fait cette boucle dans l'état actuel des choses ?

    J'avais lâché le fil de ta discussion précédente.
    Du coup je me demande :
    C'est quoi cette variable taille dans dans ta boucle while (pas celle que tu viens d'ajouter : l'autre), à quoi correspond-elle ? Es-tu sure de faire ta recherche sur le nombre d'élément qu'il faut ?

  10. #9
    Dlzlogic

    Re : if ou do while ou while??

    Bonjour,
    Citation Envoyé par bzh_nicolas
    Les instructions break étaient surtout utiles lorsque l'on devait optimiser à fond un programme en économisant au maximum la mémoire et l'utilisation du processeur, ce n'est plus le cas aujourd'hui.
    J'ajouterai que ce n'est pas du tout formateur pour quelqu'un qui débute en programmation.
    C'est assez curieux l'usage de l'imparfait pour l'instruction "break". Cette instruction est une instruction comme une autre, ni meilleure, ni moins bonne.
    Il faudrait aussi expliquer pourquoi on ne devrait plus optimiser un programme.
    Je pense que vous devriez rectifier votre message en modérant vos affirmations.

    Quant à Celine, elle débute apparemment seule, elle a droit qu'on l'aide, et pas forcément en caractères gras.

  11. #10
    whoami

    Re : if ou do while ou while??

    bonjour,
    Citation Envoyé par Dlzlogic Voir le message
    Quant à Celine, elle débute apparemment seule, elle a droit qu'on l'aide, et pas forcément en caractères gras.
    C'est vrai, mais ça commence à faire pas mal de temps qu'elle est débutante sur ce forum, et à ce titre, elle devrait avoir assimilé les notions basiques qui sont évoquées dans ce sujet.

    Et donc, papier + crayon sont impératifs, ainsi que ne pas écrire la moindre ligne de code tant qu'on n'a pas trouvé et compris un algorithme résolvant le problème du jour (sinon, on aboutit au problème actuel : du code écrit sans vraiment savoir où on va, tentatives de le modifier, toujours sans avoir réellement compris ce qu'on fait, ...).

  12. #11
    Dlzlogic

    Re : if ou do while ou while??

    OK,
    Je n'ai pas assez d'ancienneté sur ce forum pour m'en être rendu compte. Il est vrai que j'ai été un peu étonné de constater qu'elle n'avait pas suivi mes conseils d'initialiser un compteur dans la boucle.

  13. #12
    bzh_nicolas

    Re : if ou do while ou while??

    Citation Envoyé par Dlzlogic Voir le message
    Bonjour,
    C'est assez curieux l'usage de l'imparfait pour l'instruction "break". Cette instruction est une instruction comme une autre, ni meilleure, ni moins bonne.
    Il faudrait aussi expliquer pourquoi on ne devrait plus optimiser un programme.
    Je n'ai pas dit qu'on ne devait pas optimiser un programme, j'ai simplement dit que les breaks rendent un code plus difficile à relire, à comprendre et à débogguer. D'ailleurs, ça fait un bout de temps les profs d'informatique déconseille ce genre de construction pour les raisons suscitée. Il y en a plusieurs sur ce forums, ils pourront te le confirmer.

    D'ailleurs en parlant d'optimisation remplacer un while à 2 conditions par un for avec un break revient à simplement à supprimer un test par tour de boucle. C'est ce genre d'optimisation qui n'est plus très utiles à l'heure actuelle car peu couteuse en temps processeur (surtout par rapport aux nombres d'instructions exécutées dans la boucle).

  14. #13
    polo974

    Re : if ou do while ou while??

    Sans break, comment on fait dans les switch()....

    Moi, je regrette parfois l'absence de paramètre au break, on ne peut sortir que d'un niveau à la fois, alors que parfois dans un boucle contenant un switch, il serait sympa de pouvoir "breaker" de 2 niveaux. Actuellement, on est obligé de positionner une variable de condition de sortie de boucle.

    De la même façon, on peut critiquer les return() éparpillés dans une fonction, mais parfois, c'est tout de même plus simple de le faire plutôt que d'imbriquer ou chainer les if pour n'avoir qu'un return en fin de fonction.

    Bon, sinon, il reste toujours le goto (bien crade celui là, mais avec setjump et longjump, on peut faire pire (ou mieux selon le point de vue) ).

    Quant à dire que de nos jour avec les processeurs qu'on a, ce n'est plus la peine d'optimiser, je trouve ça dommage, car il n'y a pas que le monde du PC gigaHertzien, et même à ce niveau, c'est dommage de gaspiller de la ressource ("zut, ma batterie est déjà vide...").
    Jusqu'ici tout va bien...

  15. #14
    Dlzlogic

    Re : if ou do while ou while??

    Bonjour bsh_nicolas
    Code:
    D'ailleurs en parlant d'optimisation remplacer un while à 2 conditions par un for avec un break revient à simplement à supprimer un test par tour de boucle. C'est ce genre d'optimisation qui n'est plus très utiles à l'heure actuelle car peu couteuse en temps processeur (surtout par rapport aux nombres d'instructions exécutées dans la boucle).
    Si j'ai proposé une boucle for avec un break, ce n'était pas dans un but d'optimisation, mais de logique de traitement : on cherche quelque-chose, quand on l'a trouvé, ce n'est plus la peine de chercher et un risque que le dernier élément testé apparaisse comme l'élément trouvé.
    Par ailleurs, si on connait le nombre de boucles à faire, la boucle for est de loin préférable.
    A mon avis les boucles do et do ... while devraient être réservées lorsque l'évènement qui fera sortir de la boucle ne peut pas être prévu, c'est à dire, pas un compteur (sauf sécurité).

    De toute façon ce sujet (Celine) n'a aucun rapport avec des problèmes de performance, pais de logique élémentaire.

  16. #15
    whoami

    Re : if ou do while ou while??

    Bonjour,
    Citation Envoyé par polo974 Voir le message
    Sans break, comment on fait dans les switch()....
    Ça n'a rien à voir avec son utilisation dans une boucle.

  17. #16
    Dlzlogic

    Re : if ou do while ou while??

    Bonjour,
    L'instruction break est une instruction comme les autres. Elle fait partie de nombreux langages. C'est une instruction de branchement inconditionnel au même titre que goto, continue, return etc.
    L'instruction goto a un mauvais passé (ou pourrait presque dire passif, ie un casier judiciaire assez chargé) à cause de son utilisation en Basic, et aussi en Fortran. Mais essayez donc de compiler du C avec un goto mal utilisé et vous me raconterez.
    L'instruction break a été introduite, je pense, avec le switch, avec la réaction "qui c'est celle-là". J'ai même lu dans un document d'aide aux débutants que les instructions case devaient être terminées par un break.
    Je pense réellement que toute discussion concernant la meilleure qualité d'une instruction ou d'une autre est sans objet. Quand on développe, il est indispensable de savoir se relire, savoir débuger, et pouvoir être relu.

    Petite précision concernant le switch.
    Soit une séquence qui teste un grand nombre de valeurs du genre
    if (...)
    {
    }
    else if(...)
    {
    }
    else if(....)
    {
    } etc.
    L'utilisation de switch(...) et les case ...: correspondantes donne de meilleurs résultats en termes de performance.

  18. #17
    whoami

    Re : if ou do while ou while??

    Bonjour,
    Citation Envoyé par Dlzlogic Voir le message
    L'utilisation de switch(...) et les case ...: correspondantes donne de meilleurs résultats en termes de performance.
    Pas forcément, ça dépend de la bonne implémentation du langage pour le compilateur utilisé (mais c'est souvent vrai pour les compilateurs modernes, "souvent vrai" ne signifie pas "toujours").

    Et pour le break à la fin de chaque case dans un bloc switch, il est effectivement nécessaire, sinon le programme continue à exécuter les case suivants (ça a été défini ainsi volontairement, pour pouvoir gérer un même bloc d'instructions pour plusieurs case successifs).
    Dernière modification par JPL ; 22/07/2011 à 17h52. Motif: Correction de balise

  19. #18
    Dlzlogic

    Re : if ou do while ou while??

    Pas forcément, ça dépend de la bonne implémentation du langage pour le compilateur utilisé (mais c'est souvent vrai pour les compilateurs modernes, "souvent vrai" ne signifie pas "toujours").
    Cette question a fait l'objet de tests et d'examen du code généré etc. Le principe est que un switch provoque un branchement direct, alors que if else() induit un test.
    Il est bien évident que pour 5 tests c'est insensible, mais pour plusieurs dizaines il vaut mieux le savoir.

    Et pour le break à la fin de chaque case dans un bloc switch, il est effectivement nécessaire, sinon le programme continue à exécuter les case suivants (ça a été défini ainsi volontairement, pour pouvoir gérer un même bloc d'instructions pour plusieurs case successifs).
    Si on veut sortir du case, oui, naturellement. C'est à dire il est nécessaire si et seulement si on veut sortir du bloc. C'est une instruction à part entière son utilisation dépend d'un choix du développeur.

  20. #19
    bzh_nicolas

    Re : if ou do while ou while??

    Citation Envoyé par Dlzlogic Voir le message
    Bonjour bsh_nicolas
    Si j'ai proposé une boucle for avec un break, ce n'était pas dans un but d'optimisation, mais de logique de traitement : on cherche quelque-chose, quand on l'a trouvé, ce n'est plus la peine de chercher et un risque que le dernier élément testé apparaisse comme l'élément trouvé.
    C'est ce que faisait déjà la boucle while originale : elle s'arrête dès que la variable trouve vaut 1.

  21. #20
    Dlzlogic

    Re : if ou do while ou while??

    Bonjour bzh_nicolas
    Je n'ai jamais dit que on ne sortait pas de la boucle while.
    Je suis allé revoir l'origine de cette discussion, le la cite ci-dessous.
    C'est pas terrible ce genre de code, les breaks sont efficaces et fonctionnent bien mais sont de mauvaises habitudes de programmation. S'ils se retrouvent en nombres dans un programmes, ils peuvent rapidement rendre du code illisible et difficile à déboguer.
    Les instructions break étaient surtout utiles lorsque l'on devait optimiser à fond un programme en économisant au maximum la mémoire et l'utilisation du processeur, ce n'est plus le cas aujourd'hui.
    J'ajouterai que ce n'est pas du tout formateur pour quelqu'un qui débute en programmation.
    J'ai simplement dit que je proposais un autre code qui me parait meilleure. Ceci, naturellement dans un but pédagogique et non un but de performance. A l'évidence nous n'avons pas les mêmes habitudes de programmer, est-ce grave ? Ceci montre qu'il n'y a pas qu'une seule vérité en manière de programmation. Quant au break, pour moi, c'est plus clair de voir un beau break dans un boucle for que d'avoir à déchiffrer une ligne de test, tout accolé, et où en particulier la variable testée n'apparait pas dans le module. Par contre ce dont je suis sûr, c'est que lorsque on parle de l'instruction break, on ne doit pas en parler à l'imparfait mais au présent.
    Il n'a pas d'instruction meilleure que d'autre, mais il y a les bonnes pratiques et les moins bonnes. Il y a aussi les pratiques que je préfère à d'autres en fonction des cas, j'essaye de faire partager mes préférences.