IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C Discussion :

Que pensez vous du goto [Débat]


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 37
    Par défaut
    Citation Envoyé par gege2061
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if( ligne[i] == 2 )
    {  /* traitement du champ2 */ }
    else if ( lign[i] == 1 || ligne[i]==3 )
    { /* traitement du champ3 */ }
    else{ /* traitement du champ1 */}
    iagine ce que ça donne avec une centaine de champs, quand tous saufs le dernier ne sont pas présents.... tu marques un if avec cent tests dedans? Pas très lisible tout ça...

  2. #2
    Membre averti
    Homme Profil pro
    Consultant informatique en retraite
    Inscrit en
    Décembre 2010
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Consultant informatique en retraite
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2010
    Messages : 29
    Par défaut
    Bonjour,

    Le "goto" c'est très bien si on ne l'utilise qu'à bon escient !
    Il est, à mon avis, parfaitement correct d'utiliser cette instruction décriée
    dans le cas des traitements d'erreur où il est nécessaire de stopper l'exécution du programme sans autre forme de réflexion, le "goto" renvoie à la routine d'erreur qui termine le programme ou la fonction.
    J'ai aussi vu des utilisations du "goto" (en COBOL) pour envoyer directement à la fin d'une procédure utilisée en "PERFORM".

    Dans les autres cas il vaut mieux éviter le "goto" qui rend souvent le code plus difficile à lire. Quoique les "bardées" de "if" imbriqués ne soient pas plus faciles a suivre s'il y a (je l'ai déjà vu) plus de deux niveaux d'imbrication. Mais il s'agit là plus d'une mauvaise structuration du code...

    Cordialement

  3. #3
    Membre très actif
    Avatar de edfed
    Profil pro
    être humain
    Inscrit en
    Décembre 2007
    Messages
    476
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : être humain

    Informations forums :
    Inscription : Décembre 2007
    Messages : 476
    Billets dans le blog
    1
    Par défaut
    je code en asm, j'ai pas encore implémenté tout dans ma lib, mais le goto n'est pas prévu du tout. pour la simple raison que le goto, il est souvent implicite.

    remarquez donc que la boucle for est obligée de faire un test, puis un branchement conditionnel, donc, un goto conditionnel.

    je dirait que l'utilisation du goto peut être cool si utilisé à l'intérieur d'une fonction, sans jamais en sortir.
    si l'on doit faire un goto vers un truc en dehors de notre fonction, il faut alors passer un paramètre indiquant le goto à faire avant de sortir de la fonction, puis avec un petit bout de code, effectuer notre goto à l'intérieur d'une condition.

    le goto est implicite dans tellement d'instructions C de base qu'il est inutile de les lister.

    le goto pur, lui, c'est juste un ordre pour signaler qu'il faut changer de bout de code, un peut comme si l'on faisait de la gestion de multitache, des trucs de système, pas des trucs d'applications.

    cela dit, personne n'interdit un codeur de créer un microsysteme dans une application, pour gérer des choses, et utiliser des gotos, en général un seul dans la fonction tache_exec(), et utiliser des gotos dans le code principal pour appeler périodiquement la fonction tache_exec(), sans se soucier du contexte, ce quyi revient en fait à une interruption, ce qui est un goto asynchrone, périodique ou non.

    mais bon, il y a le call, c'est à dire appel de fonction, qui permet de faire encore mieux.

    donc, le goto passe à la trappe. même en asm, car jmp semble plus approprié pour signifier l'action du goto.

    et oui, on jumpe, on saute littéralement dans une autre partie de code. une action nette.

    j'ai pris au hasard un code asm, et j'en ai isolé le nombre de JMP purs (goto).

    j'ai trouvé une fonction avec 5 goto (jmp) à l'intérieur

    et je vais en faire une petite analyse simple.
    Code asm : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
      proc MainDlg hdlg, msg, wparam, lparam
        push    ebx esi edi
        cmp     [msg], WM_INITDIALOG ;case WM init dialog
        je      .wminitdlg ;on fait donc ce qui est là bas.
        cmp     [msg], WM_COMMAND ;idem, autre case
        je      .wmcommand ;autre case, autre routine
        cmp     [msg], WM_CLOSE ;encore un case
        je      .wmclose;etc..
        xor     eax, eax ;retourner 0 car on à rien fait, eax, c'est le return ? du C
        jmp     .finish ;on a terminé les cases, donc, endcase
        .wminitdlg:;case 1
          invoke  capCreateCaptureWindow, _camtitle, WS_VISIBLE + WS_CHILD, 10, 10,\
                                            266, 252, [hdlg], 0
          mov     [hWebcam], eax
          jmp     .finish ;ho, on a encore fini notre bout de case
        .wmcommand:;case 2
          cmp     [wparam], BN_CLICKED shl 16 + ID_START
          je      .startbutton ;case2.1
          cmp     [wparam], BN_CLICKED shl 16 + ID_STOP
          je      .stopbutton ;case2.2
          cmp     [wparam], BN_CLICKED shl 16 + ID_CLICK
          je      .clickbutton ;case2.3
        .wmclose:
          invoke  SendMessage, [hWebcam], WM_CAP_DRIVER_DISCONNECT, _camtitle, 0
          invoke  EndDialog, [hdlg], 0
     
     
    ;on sort ici, notre endcase, endfor, endif, end_quelque_chose...
        .finish:
          pop     edi esi ebx ;petit bout d'out-it impossible à contourner, sinon crack!!!
          ret
     
        .startbutton: ;case2.3
          invoke  SendMessage,  [hWebcam], WM_CAP_DRIVER_CONNECT, [nDevice], 0
          invoke  SendMessage,  [hWebcam], WM_CAP_SET_SCALE, TRUE, 0
          invoke  SendMessage,  [hWebcam], WM_CAP_SET_PREVIEWRATE, [nFPS], 0
          invoke  SendMessage,  [hWebcam], WM_CAP_SET_PREVIEW, TRUE, 0
          jmp     .finish ;fini le case
        .stopbutton:;case2.2
          invoke  SendMessage, [hWebcam], WM_CAP_DRIVER_DISCONNECT, _camtitle, 0
          jmp     .finish ;etc...
        .clickbutton:;case2.1
          invoke  SendMessage, [hWebcam], WM_CAP_FILE_SAVEDIB, 0, _filename
          jmp     .finish;etc...
      endp
    case1 ou case2
    dans case2, il y a 3 sous cases.
    et tous font partie de la même fonction, qui est mainDlg, la fonction de dialogue principale d'une application win32, donc, du code système pour faire simple.
    ce type de code est généré par le compilo C, ou le codeur ASM, mais pas le codeur C.

    tout ces goto vont au même endroit, l'étiquette .finish n'est qu'une adresse dans le code.
    ce sont de simples raccourcis vers la sortie.
    ils sont indispensables dans un code machine, car en théorie, le cpu ne voit qu'une ligne de code à la fois, pas 30 comme nos éditeurs de texte, et donc, il lui faut bien des indications pour lui montrer la sortie de la fonction.

    en C, ces jmp sont invisibles, ils sont implicites.
    par exemple, pour exécuter un simple if x=0 x++, le CPU à besoin d'un:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    cmp [x],0   ;x est egal à 0?
    jne LA       ;non, on saute LA
    inc [x]       ;oui, alors on va incrémenter x, x++
    LA:         ;on arrive LA si x est différent de 0, ou à la fin de notre x++
    évidement, le if n'est pas traduit ainsi dans GCC, il en faut bien plus, pour mettre en forme toutes les données, et exploiter le résultat...

    mais l'idée est là, le goto est conditionnel, et implicite.

    si l'on ajoute une ou deux conditions de tests, on aura tout à gagner à faire un case.
    et lors de chaque tests de case, il y aura lieu de sortir en cas de résultat positif.
    le goto est encore une fois implicite.

    je ne connais pas encore l'instruction case du C, je débute dans deux jours seulement.
    mais en gros, lorsqu'un cas est rencontré, il est inutile de continuer les tests, il faut donc sortir du case. et donc, chaque cas possède son petit bout de code, terminé par un jmp .finish, c'est à dire un goto .FIN.

    et en parlant de fin, le goto est utile en prog système, car doit surement être encodé directement en jmp (enfin, j'espère). ce qui explique qu'il ne faut pas l'utiliser dans le code C, car si vous voyez le résultat de la compilation d'une fonction C, mettre un JMP dedans, c'est du suicide. les initialisations sont nombreuses, et sortir ou entrer dans passer par ces initialisations est le danger évoqué sur le GOTO

    le goto ne doit donc pas sortir d'une fonction.

    évidement, ça peut fonctionner car par exemple, notre code ne fait rien de complexe et donc, notre goto n'a aucune influence sur le reste.

    mais si on devient un vrai programmeur, qu'on fait la maintenance du code, on va vite s'apercevoir que les goto (jump forcés), sont vraiment inutiles, et obligent à frapper 40 fois plus de code pour corriger les problèmes d'init et out-it de fonctions.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juin 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2010
    Messages : 6
    Par défaut
    Le goto n'est pas dangereux s'il est utilisé ponctuellement et intelligemment. Utiliser un héritage de l'assembleur n'est pas un crime. Il faut cependant bien faire attention à ce qu'on fait avec un goto. De nombreux logiciels/bibliothèques bas niveau l'utilisent (noyau linux, GCC ABI c++).

    Un exemple d'utilisation méritant la pendaison :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    funcA()
    {
         goto Etiq;
    }
     
    funcB()
    {
    Etiq:
       // traitements
    }

    Un exemple d'utilité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     
    for ()
    {
           while ()
           {
                     for()
                     {
                               if (resultat_trouvé)
                                  goto End;
                     }
           }
    }
     
    End:
          // cool !
    Maintenant, est-ce qu'un enchaînement de boucles est vraiment nécessaire ? On pourrait aussi mettre la condition d'arrêt dans toutes les boucles, ce qui peut allourdir la lisibilité du code.

    Si on dit que goto réduit à néant un code structuré, qu'en est-il de break et continue ? Ce sont des sauts inconditionnels aussi... mais limités ! Alors goto n'est pas plus dangereux qu'un break ou un continue, seulement il faut savoir l'utiliser correctement pour éviter de déstructurer complètement son code.

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par artefactman Voir le message
    Si on dit que goto réduit à néant un code structuré, qu'en est-il de break et continue ? Ce sont des sauts inconditionnels aussi... mais limités ! Alors goto n'est pas plus dangereux qu'un break ou un continue, seulement il faut savoir l'utiliser correctement pour éviter de déstructurer complètement son code.
    A vrai dire, dans mon code perso, je n'utilise le break que dans une seule situation : entre deux cas d'un test à choix multiple (case d'un switch), et jamais de continue...

    Il y a tout à fait moyen de s'en passer dans les autres cas, d'autant plus que le simple fait d'imbriquer trois boucles mériterait presque lui aussi la pendaison

    J'ai énormément de mal à envisager une situation dans laquelle trois boucles seraient imbriquées dans laquelle le principe de la responsabilité unique serait malgré tout respecté, et j'ai déjà repris pas mal de code dans ce sens :

    Si une fonction ne doit avoir qu'une seule boucle non imbriquée et qu'elle doit se contenter d'appele une autre fontion qui contiendra la boucle "réellement active", pour moi, cela mérite d'être fait.

    Et si, pour sortir de cette boucle, un return s'avère utile dans le cas où une condition est remplie, on sait au moins exactement où l'on va se retrouver par la suite
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 480
    Par défaut
    Citation Envoyé par koala01 Voir le message
    et jamais de continue...
    C'est dommage parce que continue a un avantage non-négligeable dans le cas de for : celui d'honorer dans tous les cas la post-condition (généralement l'incrémentation de la variable). L'autre solution consiste à faire un if qui englobe tout ce qui aurait suivi le continue. Les deux approches se valent.

    J'ai énormément de mal à envisager une situation dans laquelle trois boucles seraient imbriquées dans laquelle le principe de la responsabilité unique serait malgré tout respecté, et j'ai déjà repris pas mal de code dans ce sens :
    Ben, chaque fois que l'on a affaire à plusieurs dimensions :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        int tab[10][10][10];
     
        int longueur;
        int largeur;
        int hauteur;
     
        for (hauteur =0;hauteur <10;hauteur++)
        for (largeur =0;largeur <10;largeur++)
        for (longueur=0;longueur<10;longueur++) tab[hauteur][largeur][longueur] = 0;

    Si une fonction ne doit avoir qu'une seule boucle non imbriquée et qu'elle doit se contenter d'appele une autre fontion qui contiendra la boucle "réellement active", pour moi, cela mérite d'être fait.
    'faut se méfier des grands principes énoncés en programmation. Généralement, ils permettent d'identifier un cas de figurer récurrent en informatique et de s'y pencher scientifiquement. Mais c'est aussi bien souvent une manière d'inhiber le libre arbitre du codeur. Tout ces principes ne sont pas forcément valables, et ils sont généralement trop jeunes pour qu'on en fasse des dogmes.

    Dans le cas du principe de la responsabilité unique, bon nombre de gens soulèvent justement le problème de sa granularité ; jusqu'où faut-il pousser le vice ?

    Et si, pour sortir de cette boucle, un return s'avère utile dans le cas où une condition est remplie, on sait au moins exactement où l'on va se retrouver par la suite
    Même chose avec un break, un continue et une fin de boucle ordinaire. Reconnais que trois fonctions pour les boucles ci-dessus seraient de trop, surtout si on tient compte du fait qu'elles sont les composantes indissociables de l'espace qu'elles forment.

  7. #7
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    C'est dommage parce que continue a un avantage non-négligeable dans le cas de for : celui d'honorer dans tous les cas la post-condition (généralement l'incrémentation de la variable). L'autre solution consiste à faire un if qui englobe tout ce qui aurait suivi le continue. Les deux approches se valent.



    Ben, chaque fois que l'on a affaire à plusieurs dimensions :

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
        int tab[10][10][10];
     
        int longueur;
        int largeur;
        int hauteur;
     
        for (hauteur =0;hauteur <10;hauteur++)
        for (largeur =0;largeur <10;largeur++)
        for (longueur=0;longueur<10;longueur++) tab[hauteur][largeur][longueur] = 0;
    Sauf que, remis dans l'optique où un goto, un break ou un continue serait nécessaire, la fonction ne se contentera que rarement de mettre un élément à 0, et que, très souvent, il y aura des instructions dans les trois niveaux d'imbriquations
    'faut se méfier des grands principes énoncés en programmation. Généralement, ils permettent d'identifier un cas de figurer récurrent en informatique et de s'y pencher scientifiquement. Mais c'est aussi bien souvent une manière d'inhiber le libre arbitre du codeur. Tout ces principes ne sont pas forcément valables, et ils sont généralement trop jeunes pour qu'on en fasse des dogmes.
    Je te l'accorde sans aucun problème!

    Mais, encore une fois, mis dans le contexte ou break, goto ou continue s'avèrent nécessaires, ils ont l'avantage de te forcer à garder des fonctions "aussi simples que possibles", et tout le monde y gagne
    Dans le cas du principe de la responsabilité unique, bon nombre de gens soulèvent justement le problème de sa granularité ; jusqu'où faut-il pousser le vice ?
    jusqu'au point adapté à la situation

    Cette "réponse de normand" n'apporte peut être pas beaucoup d'éclaircissement, mais elle permet de généraliser et d'exprimer la notion que j'essaye de faire passer : une fonction ne devrait avoir à s'occuper que d'une seule ressource et ne devrais pas avoir à la modifier de plus d'une manière.

    Si une fonction doit gérer plus d'une ressource ou si elle doit la modifier de plus d'une manière, il est sans doute intéressant de prévoir une fonction plus "atomique" pour chaque modification à apporter et une autre pour chaque ressource à gérer, de manière à ce que la fonction qui, justement, doit effectuer l'ensemble du traitement n'aie "qu'à appeler" les trois ou "quatre fonctions plus basiques", qu'il sera sans doute utile de pouvoir appler séparément dans certaines situations
    Même chose avec un break, un continue et une fin de boucle ordinaire. Reconnais que trois fonctions pour les boucles ci-dessus seraient de trop, surtout si on tient compte du fait qu'elles sont les composantes indissociables de l'espace qu'elles forment.
    Bien que la fonction ne présente ni break, ni goto, ni continue, je reconnais que ce serait un peu exagéré pour cette fonction particulière, non pas parce que les boucles font partie d'un espace indissociable, mais bien parce que la fonction elle même reste suffisamment simple pour ne pas (forcément) justifier le fait de la scinder en trois...

    Et encore!!! Pour moi, tout code devant être écrit plus d'une fois justifie le fait de créer une fonction particulière, et donc, si pour une raison ou une autre tu en venais, à un moment donné, à n'écrire ne serait ce qu'un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for(int i=0;i< MAXI;++i)
        truc[A][B][i]=0;
    il serait peut etre intéressant d'envisager la création d'une fonction setLineToZero(int A, int B)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  8. #8
    Membre Expert
    Avatar de Ti-R
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Avril 2003
    Messages
    1 683
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 683
    Par défaut
    Bizarre je n’ai jamais utilisé de goto...
    Pourtant je code souvent...
    Alors on pourrait s'en passer ??
    A par dans de très très très rare cas...

  9. #9
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par ulukahio
    iagine ce que ça donne avec une centaine de champs, quand tous saufs le dernier ne sont pas présents.... tu marques un if avec cent tests dedans? Pas très lisible tout ça...
    Non, je revoie ma façon de codée

  10. #10
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2004
    Messages : 66
    Par défaut
    Citation Envoyé par Ti-R
    Bizarre je n’ai jamais utilisé de goto...
    Pourtant je code souvent...
    "Coder" .. ça ne veut rien dire ... tout dépend si tu fais du temps-réel critique (genre switch en bas de la ms avec un OS très performant) ou si tu fais des applications plus standard

    Alors on pourrait s'en passer ??
    A par dans de très très très rare cas...
    Dans la mesure du possible, oui, mais c'est un peu comme l'école qui refuse les "continue" dans les for

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 37
    Par défaut
    Citation Envoyé par gege2061
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if( ligne[i] == 2 )
    {  /* traitement du champ2 */ }
    else if ( lign[i] == 1 || ligne[i]==3 )
    { /* traitement du champ3 */ }
    else{ /* traitement du champ1 */}

    la même avec les switch:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    switch( ligne[i] )
    {
      case 2:
        /* traitement du champ2 */
      break;
      case 1:
      case 3:
        /* traitement du champ3 */
      break;
      default:
        /* traitement du champ1 */
      break;
    }
    Si les sont peu utiliser c'est qu'ils sont facilement remplassable.
    sauf que pour mon programme ce switch marche mais est tres lourd à programmer... Pourquoi? Parcequ'il il faudrait que je l'écrive cent fois:

    En effet, la valeur de ligne [i] ne correspond pas au champ dans lequel se placer, mais au nombre de champs à sauter. Donc le case 3 peut m'emmener dans le champ 3 comme dans le champ 10, et il faudrait que je mette ce switch à chaque fois que je teste la valeur de ligne[i] avec un corps différent. Et du coup je vois pas ce que je gagne en lisibilité.

  12. #12
    Membre éclairé Avatar de calogerogigante
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Avril 2003
    Messages
    608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2003
    Messages : 608
    Par défaut
    Une autre piste pour ton problème, à condition que tes ligne[i] renvoit toujours des entiers:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    main(...)
    {
    traitement_champs(ligne[i]);
     
    //....
    }
     
    void traitement_champs(int nombre)
    {
    switch(nombre)
      {
       case 1: // traitement champs 1
     
       case 2: // traitement champs 2
     
       case 3: // traitement champs 3
     
      default: // traitement divers...
      }
     
    }
    Bien sûr, tu modifies le type de retour "void" de la fonction en ce que tu aurais besoin de récupérer éventuellement...

    Enfin, c'est dur de proposer une solution sans avoir tous les tenants et les aboutissants du problème...
    C'est juste une piste...

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 37
    Par défaut
    Citation Envoyé par gege2061
    Citation Envoyé par ulukahio
    iagine ce que ça donne avec une centaine de champs, quand tous saufs le dernier ne sont pas présents.... tu marques un if avec cent tests dedans? Pas très lisible tout ça...
    Non, je revoie ma façon de codée
    je ne demande que ça... Je ne suis absolument pas un programmeur né et je ne demande qu'à faire des progrès.

  14. #14
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Citation Envoyé par mat.M
    C'est vrai il faut éviter les goto mais parfois c'est bien utile .....
    Dans les exemples du SDK de Direct X il y a utilisation de quelques goto .
    Ils sont vraiment mauvais programmeurs alors chez M$
    Je suis d'accord que chez Micro$oft ils ne sont pas complètement nuls, mais quand même, ils pourraient faire quelques efforts :
    Tiré de MSDN
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    BOOL ProcessCmdLine(LPSTR lpCmdLine, LPDWORD pdwRegisterCF,
                   LPDWORD pdwRegisterActiveObject, int nCmdShow)
    {
       LPCLASSFACTORY pcf = NULL;
       HRESULT hr; 
       *pdwRegisterCF = 0;
       *pdwRegisterActiveObject = 0;
     
       // Expose class factory for application object if command line
       // contains the /Automation switch.
       if (_fstrstr(lpCmdLine, "-Automation") != NULL
          || _fstrstr(lpCmdLine, "/Automation") != NULL)
       {
          pcf = new CApplicationCF;
          if (!pcf)
             goto error;
          pcf->AddRef();
          hr = CoRegisterClassObject(CLSID_Lines, pcf,
                            CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE,
                            pdwRegisterCF);
          if (hr != NOERROR)
             goto error;
          pcf->Release();
       }
       else            // Show window if started as stand-alone. 
       g_pApplication->ShowWindow(nCmdShow );
     
    // Register Lines Application object in the running object table 
    // (ROT). Use weak registration so that the ROT releases its reference
    // when all external references are released.
       RegisterActiveObject(g_pApplication, CLSID_Lines, ACTIVEOBJECT_WEAK,
             pdwRegisterActiveObject);
       return TRUE;
     
    error:
       if (pcf)
          pcf->Release();
       return FALSE;
    }
    Le goto est-il vraiment utile ici ??
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  15. #15
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2004
    Messages : 66
    Par défaut
    Citation Envoyé par ulukahio
    En effet, la valeur de ligne [i] ne correspond pas au champ dans lequel se placer, mais au nombre de champs à sauter.
    Peux-tu poster ton code de traitement de champs qu'on comprenne un peu plus ce que tu veux dire ?

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 37
    Par défaut
    Citation Envoyé par calogerogigante
    Citation Envoyé par ulukahio
    Oui je suis d'accord avec toi, mais ce n'est pas dans ce type de circonstances que je compte utiliser goto.

    (on est à l'intérieur d'une boucle while qui lit une par une les lignes d'un fichier texte)

    Si quelqu'un pouvait me donner un code propre et sûr correspondant à celui ci:

    if (ligne[i]==2) //le chiffre correspond au nombre de champs non présents dans la base d'origine
    goto champ2;
    else if (ligne[i]==3)
    goto champ3;
    else{ //traitement du champ1}

    champ2: //traitement du champ2

    if (ligne[i]==1)
    goto champ3;

    champ3: //traitement du champ 3
    Là par contre, en effet, je trouve déjà l'utilisation du goto risquée... Très risquée...

    Plutôt d'accord avec les propositions des deux posts au-dessus de celui-ci...
    En quoi cette utilisaation est elle risquée? (par contre trap D, si on pouvait éviter de faire dévier le topic sur l'incapacité à programmer des gens de grosoft ça m'arrangerait )

  17. #17
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par Trap D
    Tiré de MSDN
    Le goto est-il vraiment utile ici ??
    Effectivement dans ce cas, il est possible de faire une fonction mais je trouve que le programme est clair quant même. Je n'est pas mis plus de temps à comprendre le programme que s'il y avait eu une fonction. Contrairement au code de ulukahio.

  18. #18
    Membre averti
    Profil pro
    Inscrit en
    Février 2005
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 37
    Par défaut
    Citation Envoyé par DavG
    Citation Envoyé par ulukahio
    En effet, la valeur de ligne [i] ne correspond pas au champ dans lequel se placer, mais au nombre de champs à sauter.
    Peux-tu poster ton code de traitement de champs qu'on comprenne un peu plus ce que tu veux dire ?

    un exemple: le fichier original contient une centaine de champs présentés comme suit:
    Michel; Barnier; 21rue machin; c'est la fête
    mais si le premier champ n'est pas présent, on a:

    1; Barnier; 21rue machin; c'est la fête
    si le premier et le deuxième ne sont pas présents, on a:

    2; 21rue machin; c'est la fête
    Si le premier, le deuxieme et le troisieme ne sont pas présents:

    3; c'est la fête
    Si le deuxieme n'est pas présent:

    Michel; 1; 21rue machin; c'est la fête
    Si le deuxieme et le troisieme ne sont pas présents:

    Michel; 2; c'est la fête
    Et ainsi de suite...

  19. #19
    Membre éclairé Avatar de calogerogigante
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Avril 2003
    Messages
    608
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2003
    Messages : 608
    Par défaut
    Au plus tu rajoutes de "petits jump" à saute mouton au-dessus de petits bouts de code, au plus tu risques de louper une étape logique du déroulement de ton code... Surtout si tu dis toi-même qu'il risque d'y avoir une centaine de traitements de champs...

    Je ne suis pas foncièrement contre, mais je trouve cela dangereux car tu risques de louper plus facilement une incohérence dans ton code...
    A moins d'être sûr de ce que tu fais à 100 % (exemple: t'as écrit un petit ordinogramme clair qui représente toutes les possibilités de cette partie de ton programme utilisant les gotos...), alors OK...

    Mais à mon avis: ordonner les choses clairement avec un switch, dans ton cas, serait beaucoup plus propre et plus lisible... Notamment en cours de déboguage...

  20. #20
    HRS
    HRS est déconnecté
    Membre chevronné
    Avatar de HRS
    Inscrit en
    Mars 2002
    Messages
    678
    Détails du profil
    Informations forums :
    Inscription : Mars 2002
    Messages : 678
    Par défaut
    il faut se rappeler que les instructions "return", "break", "continue"
    sont des "goto" déguisés et maîtrisés

    par contre il n'existe aucune instruction pour sortir élégamment de
    2 boucles imbriquées. à part "goto".

+ Répondre à la discussion
Cette discussion est résolue.
Page 3 sur 8 PremièrePremière 1234567 ... DernièreDernière

Discussions similaires

  1. Que pensez-vous des générateurs de doc PHP ?
    Par Nonothehobbit dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 64
    Dernier message: 10/07/2007, 10h17
  2. Que pensez vous de filemaker
    Par thpopeye dans le forum Autres SGBD
    Réponses: 4
    Dernier message: 14/06/2007, 15h20
  3. Que pensez vous du nouveau kernel 2.6 ?
    Par GLDavid dans le forum Administration système
    Réponses: 58
    Dernier message: 02/08/2004, 15h45
  4. [Débat] Que pensez-vous des langages à typage dynamique?
    Par Eusebius dans le forum Langages de programmation
    Réponses: 14
    Dernier message: 16/06/2004, 12h12
  5. Que pensez vous du mariage ASP Flash?
    Par tyma dans le forum Flash
    Réponses: 4
    Dernier message: 09/07/2003, 15h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo