Par contre je suis entièrement d'accord que si l'on peut s'en passer autant le faire. Et les goto ne sont pas plus dangereux d'un getchEnvoyé par Ti-R
![]()
Par contre je suis entièrement d'accord que si l'on peut s'en passer autant le faire. Et les goto ne sont pas plus dangereux d'un getchEnvoyé par Ti-R
![]()
est-ce que tu sais ce que c'est le language assembleur et notamment celui du x86Envoyé par argoet
A quoi servent les instructions JMP , JGE etc ?? ( language C=assembleur haut niveau )
qu'est-ce qu'on fait ici ??
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 MOV AX,200 decr_ax: DEC AX CMP AX,10 JBE decr_ax
tiens ......tiens .....et dans quel livre cette maxime est statuée ??La valeur d'un programmeur est inversement proportionnel au nombre de goto que l'on trouve dans son code![]()
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$![]()
Le goto peut etre tres pratique mais doit etre utilisé avec soin. Il est notamment tres pratique pour la gestion d'erreur. Il permet notamment de creer un bloc pour les gestions d'erreurs et de centraliser la desallocation de ressources sur sortie d'erreur. En cas d'erreur il suffit de faire un goto sur un label a la suite duquel on procede à la desallocation et à la sortie de fonction. Cependant une regle pratique est d'éviter de faire un goto qui remonte le flot d'instruction, ce qui peut conduire a des cas délicats.
pour la gestion d'erreur, plutot qu'un "goto", j'aurais plutot tendance à créer une fonction englobant un exit() ou un return().Envoyé par Vigneau
Pour moi, le goto est inutile :
chaque cas d'utilisation du goto montre que le bloc d'instructions à "sauter" pourrait/devrait être intégré dans une sous-fonction + mechanisme de test de l'appel.
Je pense qu'un usage du goto montre qu'on code avant d'écrire l'algo/la spec/etc ... et ça, c'est pas bien :p
il faut aussi se poser la question du "si j'ai besoin de mettre un goto, est-ce que ça n'est pas parce que mon pgm est mal construit ?"
Démontrer qu'on peut se passer du goto ne me semble pas difficile. A coup d'ajout de if et d'utilisation de variable supplémentaire, on y arrive. Pourtant cette démonstration devrait mettre la puce à l'oreille "On est obligés de créer des variable supplémentaire" et celà est d'autant plus gênant que ces variables n'ont pas de rôle algorithmique.
Ca, c'est parfaitement intuitif. Sortir d'un bloc, quelque soit son niveau est quelque chose d'intuitif, qu'on pourrait très bien écrire dans un algorithme mathématique désitiné à l'homme et non à la machine. Mais une chose m'a choquée dans les précédents arguments c'est qu'on ait pu insister dans ce genre de cas du fait que le code ne soit pas clair. Le goto ici a bien un avantage : on nomme la sortir de boucle, ce qui permet de comprendre son sens dans l'alogorithme. Toutefois nommer une boucle, c'est très facile. Dans un exemple de boucle non imbriquée :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 for (...) { for (...) { ... goto FinDeBoucle; } } FinDeBoucle:
L'utilisation du goto dans le cas de blocs imbriqués est tellement intéressante qu'elle a été intégrée comme structure de langage dans certains langage de manière assez élégante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 for (...) // NomDeBoucleQuelconque { ... break; // Fin de NomDeBoucleQuelconque }
Et là le sens que l'on veut donner à l'instruction est parfaitement clair. Une autre structure plus récente utilisée désormais dans de nombreux langages, et qui est accessoirement la plus puissante des structures conditionnelles est la gestion des exceptions. Ces aspects inexistants en C, il ne serait pas dérangeant d'utiliser dans ces cas précis, et uniquement ces cas, l'instruction goto.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 { ... { ... break 2; } }
Mais cela ne change rien au danger que représente le goto. L'argument a été répété de nombreuses fois, ce à quoi on a répondu "Ce n'est pas plus dangereux que malloc". Malloc est dangereux, lui aussi, et c'est pour cette raison que les langages les plus récents, non soucieux de la rapidité on préférer cacher au programmeur ces jouets défendus. On ne peut malheureusement pas se passer de l'allocation dynamique, mais on peut se passer de goto, ce qui pèse relativement lourd. On a des techniques pour sécuriser l'allocation de mémoire, des "habitudes" ou des "techniques" de programmation qui permettent de limiter les erreurs. On peut certainement trouver des règles de conduites à l'usage du goto qui permettent d'éviter les dangers.
"Ne jamais utiliser de goto" est une règle qui a ses qualités. C'est un peu comme le code de la route. On doit faire des vérifications inutiles, mettre le clignotant même quand on est tout seul sur la route. Cela a de nombreux avantage en fin de compte.
- Etant donné que le débat est compliqué et que tout le monde ne le lira pas, les absents ou ceux qui lisent en diagonal ne comprendront certainement pas les réels dangers et les réels intérêts du goto, et ne connaîtront donc pas les "bonnes" utilisations du goto que ce débat pourra détacher. En conséquent, mieux vaut ne pas les utiliser du tout.
- On se pose beaucoup de questions quand on programme. Est-ce que le temps perdu à se poser des questions en vaut le bénéfice ? Est-ce que le temps qu'on passe à se demander si on utilise un goto ou non en vaut le code obtenu ? Parfois non, l'usage du goto est clair, ou au contraire, la non utilisation de goto ne complique pas le code. Très souvent sur ce sujet, j'ai vu des solutions avec goto horriblement compliquées et l'auteur aurait, je pense, tout à fait gagné à "programmer sans réfléchir sans goto".
- Les raisons qui poussent à utiliser ou non un goto sont plutôt complexe. En ce qui me concerne, je n'arriverai pas à les mettres toutes dans ma mémoire. La où c'est ennuyeux c'est pour les dangers du goto. Si je n'arrive pas à me souvenir de tous les dangers du goto (et ils sont trrrès nombreux) il m'arrivera un jour de faire une connerie avec. Autant l'éviter.
Le principal désavantage du goto est de ne pas être clair du point de vue algorithmique. Coder dans son coin des applications brouillon de quelques centaines de lignes, ce n'est pas très grave. Coder tout seul sur des projets un peu ambitieux, ou coder sur un projet où l'on est pas seul, l'usage d'un code qui n'est pas compréhensible au premier coup d'oeil devient tout de suite gênant. Et le goto a cette mauvaise idée de ne pas toujours être compréhensible au premier coup d'oeil. Sur une fonction de dix ligne, un goto interne à la fonction ne posera pas trop de problème de compréhension. Sur des fonctions un peu complexes, ou en utilisant des labels peu explicites, on arrive très vite à devoir se creuser la tête pour comprendre ce qui est écrit. C'est très traitre quand on débute en programmation et que l'on veut se lancer dans un projet. Quand on programme on a tout ce que l'on veut en tête, on sait ce que l'on fait. Et deux mois plus tard, on peut revenir sur quelque chose que l'on a écrit et ne plus rien comprendre. Se faire peur une fois suffit en général.
Remplacer le goto par une structure aproprié a un avantage capital déjà précédement énnoncé. On ne sait pas comment il est possible d'arriver à un label donné. Par contre on sait très bien quand l'identation est claire, où un bloc commence et où il s'arrête. L'utilisation des blocs de code permet de voir au premier coup d'oeil la structure d'une portion de code, ce que ne permettent pas les goto. Et c'est son principal défaut.
Il existe des branchements compliqués auxquels on a certainement tous été confrontés une fois. Une sorte de faiblesse du langage algorithmique qui oblige la répétition de code, où ce qui est mieux, l'usage de fonction. (Qui n'est pas toujours aisé étant donné qu'il faut passer un certain nombre, parfois handicapant, de paramètres)
(J'espère que je ne me trompe pas)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 Si Condition1 | ... | Aller à A ... Si Condition2 | ... | Aller à B ... A: ... B:
est un truc qu'on a appellé
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Si Condition1 | Instructions1 | Aller à A Instructions2 A:
Ici, ce qui pose problème est l'enchevetrement. En analysant les schémas d'exécution
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4Si Condition 1 Alors Instructions1 Sinon Instructions2
On a
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 Si Condition1 | Instructions1 | Aller à A Instructions2 Si Condition2 | Instructions3 | Aller à B Instructions4 A: Instructions5 B:
(Je ne sais pas si on peut trouver un problème plus simple)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 Si Condition1 | Instructions1 | Instructions5 Sinon Si Condition2 | Instructions2 | Instructions3 Sinon | Instructions2 | Instructions4 | Instructions5
Le problème dans ce code est la répétition d'instructions. On utilisera sans trop de problème une fonction Instructions2(); pour résoudre ce problème. Plutôt que de voir une répétition d'instructions, on peut voir une répétition de test de condition :
qui est une construction mécanique, ou alors pour être plus concis :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 Si Condition1 | Instructions1 Si NON Condition1 | Instructions2 Si Condition2 et NON Condtion1 | Instructions3 Si NON Condition1 et NON Condition2 | Instructions4 Si NON Condition2 | Instructions5
Ce code peut aussi être fabriqué de manière mécanique, en utilisant tant bien que mal le schéma du if-else plus haut et en repoussant les "cas non gérés" en dehors de la boucle. Ici, on a effectivement une répétition de conditions, qu'on pourra rendre moins lourde en stockant les résultat des tests dans des variables.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14Si Condition1 | Instructions1 Sinon | | Instructions2 | | Si Condition2 | | Instructions3 | Sinon | | Instructions4 | Si NON Condition 2 | Instructions5
On peut le faire, mais c'est tout à fait dommage d'y être obligé, d'autant que le C perdrait un aspect : celui d'être un macro-assembleur. On ne pourrait pas écrire en C des solutions aussi rapides qu'en assembleur, alors que cela ne concerne que des instructions courantes en assembleur. S'il est tout à fait possible qu'un code assembleur soit plus rapide qu'un code généré par un compilateur C, parce que le code assembleur utilise des optimisation avoid conditional jump à grands coup de SETcc, MOVcc, SBB, ADC ou encore utilise le parity flag ou autre spécificité du x86 c'est normal, mais que le C se fasse battre par un jeu d'instruction réduit, c'est un outrage ! Le goto permet de garder toute la puissance de l'assembleur. (Ce qui ne sert pas tous les jours, j'en conviens, mais peut servir, notement - et il y en a au moins deux ici - pour ceux qui développent des émulateurs)
Ces transformations mécaniques peuvent être en revanche, absolument pas algorithmique. L'usage des goto dans l'exemple ci-dessus peut servir pour une éxecution dont la séquence n'est pas si rare que cela. C'est un genre de code emmerdant quand on ne veut ni faire de fonction, ni faire plusieurs fois les même tests. On peut trouver des branchements à tentacule, justifiés algorithmiquement (quoiqu'en les démontrant on utilisera une des formes obtenues mécaniquement) et qui n'ont absolument aucun sens avec une série de if. Mais dans ces cas, l'algorithme est de toute façon pénible à suivre sans crayon à portée de main, et alors le bénéfice du goto n'est que logique au dépend de la lisibilité, et on ne le trouve alors pas avantageux.
Le débat du goto a commencé avec Edsger W. Dijkstra et son célèbre papier "Go To Statement Considered Harmful" (1968) et a passé par tous les états d'âmes avec des documents nommés " 'Go To Statement Considered Harmful' Considered Harmful" et " ' "Go To Statement Considered Harmful " Considered Harmful ' Considered Harmful " ... Enfin c'est un débat sans fin, mais la plus grosse contre-attaque vient de Donald E. Knuth qui publia "Structured Programming with go to Statements" (1974).
Donc moralité, goto peut très bien s'utiliser, mais il faut savoir le faire correctement et avec modération (lire "Go To Statement Considered Harmful:
A Retrospective" pour des exemples.)
À lire :
Structured Programming with go to Statements : http://portal.acm.org/citation.cfm?i...FTOKEN=6184618
Go To Statement Considered Harmful : http://www.acm.org/classics/oct95/
Go To Statement Considered Harmful: A Retrospective : http://david.tribble.com/text/goto.html
http://en.wikipedia.org/wiki/Structured_programming
http://en.wikipedia.org/wiki/GOTO
http://en.wikipedia.org/wiki/Go_To_S...idered_Harmful
Bonjour,
Je pense que poser le problème du GOTO revient à poser le problème de la bonne ou mauvaise programmation.
années 1975 : Apparition des méthodes dites de "programmation
structurée". (par opposition à la programmation dite
linéaire : Utilisation plus ou moins intensive de l'ordre
GOTO).
Avant cette époque un pgm linéaire "mal monté" (avec une profusion d'ordres GOTO) était difficilement maintenable. Il n'était pas rare de devoir "le casser" pour le ré-écrire.
Par contre un pgm convenablement "monté" (peu d'ordres GOTO) par un programmeur ayant une approche structurée nécessairement personnelle était facilement modifiable.
L'arrivée des méthodes de programmation structurées a elle aussi généré certains excès. En effet pour éviter tout GOTO, certains programmeurs structuraient tellement leur programme (sous-prog appelant un sous-sous-prog appelant lui-même un sous-sous-sous-prog......) qu'ils obtenaient le résultat inverse de celui recherché. Leur pgm étaient tout aussi difficilles à maintenir pour peu qu'ils soient conséquents.
Ces deux attitudes illustrent peut-être le problème posé.
Les discussions sur le sujet étaient fréquentes et bien entendu les avis partagés et les positions fermement arrêtées.
Pour ou contre l'emploi du GOTO dans les pgm ?
En ce qui me concerne je n'ai pas banni cet ordre qui d'ailleurs s'impose plus qu'il ne se choisit. (en gardant à l'esprit que l'on peut toujours faire autrement, mais dans quelles conditions et à quel prix ?).
Par exemple :
Un test d'optimisation (IF) accompagné d'un GOTO, programmés au début d'un sous-prog et débranchant la logique d'exécution en fin du même sous-prog si la condition est remplie, me semble raisonnable. Cela permet bien souvent d'alléger la logique principale du pgm en ne l'encombrant pas avec des tests, qui sans être inutiles, n'intéressent pas directement cette logique et par le fait l'allourdissent.
A noter également que l'ordre GOTO est bien pratique lors de la mise au point d'un pgm, lorsque l'on souhaite "sauter" une séquence suspectée d'être à l'origine de l'erreur recherchée.
La solution est simple, imaginons très fort que cette instruction n'existe pas!
Ca me ferait une belle jambeEnvoyé par Fabrice ROUXEL 1
Bonjour,
quand il s'agit d'écrire un intérpréteur , c'est obligé d'utiliser les goto, est ce qu'il y a une autre solution![]()
Turbo_chess
Je ne vois pas pourquoi ce serait obligé...
Un interpréteur est généralement plus ou moins un automate d'états fini, qui n'a pas besoin de goto...
SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.
"Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
Apparently everyone. -- Raymond Chen.
Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.
J'essaie autant que possible d'éviter les GOTO's mais je ne suis pas intégriste à ce point. Il m'arrive à l'occasion d'intégrer un GOTO RAREMENT deux.
Vous l'aurez deviné.... j'utilise beaucoup les while!!
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 int testouinon(void) // renvoit 1 si oui, renvoit 0 si non. { int a; int ch; a=o; while(a==0) { ch=getch(); switch (ch) { case 'o':a=1; return 1; case 'n':a=1; return 0; default: break; } } }
GOTO = porter préjudice à leur fièreté de programmeur, rien de plus.
Si 'on' a inventé des while et des for, c'est pas pour faire machine en arrière pour utiliser un GOTO, tu vois ce que je veux dire ?
C'est une question de principe pour ceux qui code.
PAR CONTRE: si tu fait un programme qui est destiné a être envoyé sur un microcontroleur, et bien avec un GOTO tu peux faire déborder ton stack pointeur car le saut d'adresse peut être trop grand ! donc ton programme bug![]()
Je vois rien d'autre
?Envoyé par jack_x4
il me semble qu'à l'origine il n'y a que le goto,
que le call de la programation structurée est venu plus tard et avec lui les fameux problèmes de pile
et que le goto présente sur le while et le for l'avantage de la vitesse et l'absence d'utilisation de la pile
si je devais faire un programme ou je ne souhaite aucune interception de mes adresse de sous routine par la pile, je le ferais completement en goto,
bien agencés
maintenant parlons au niveau symbolique
je trouve que la programation struturée ça fait très petit bourgeois, du genre, vas y l'alu, fait ta routine et reviens pour le jt de 20 heure, et avant de partir met tes chausson dans la pile tu les recupéreras en rentrant
bon ok, pour les gros programmes ou il y a toujours des problèmes avec le parquet...
mais le goto, lui c'est la liberté
je pars et je reviens si nos chemin se croisent encore
bon d'accord ça met le bordel pour les impots,
mais que voulez vous nos vies ressemble à nos programmes,
si nous mettons que des routines dans nos programmes
nous aurons peut être tendance à ne mettre que des routines
...dans nos vies
Goto : la seule utilisation raisonnable que je lui vois est un saut d'une procédure à une autre dans un code assembleur.
L'employer dans un algorithme itératif me semble réellement être une solution héritée d'une pratique de la programmation ancienne qui ne se veut pas réellement une transcription algorithmique.
Pour moi ça ressemble juste à une "spécificité" de microcontrôleurs. Bien sûr les branchements conditionnels, c'est bien, mais ça veut dire quoi concrétement ?
Qui veut apprendre la programmation directement depuis l'assembleur ? Les structures conditions c'est utile non, on peut faire plein de choses avec, on se creuse moins la tête aussi, et c'est plus rapide.
Goto : outil archaïque. Pourquoi l'utiliser encore, les structures de contrôles des langages évolués se substituent de façon plus élégante et plus efficace, et surtout, plus universelle aux goto.
Dans tous les cas, je crois bien qu'il est possible d'écrire n'importe quel programme sans Goto, qui est, une instruction héritée de l'assembleur (ancien), pourquoi dire encore les GOTO c'est bien ? Goto ça existe, mais en C ça fait plus rire qu'autre chose. Et bonjour la perte des avantages de la programmation structurée.
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 if (ligne[i]==2) //le chiffre correspond au nombre de champs non présents dans la base d'origine fonction_champ2(); else if (ligne[i]==3) fonction_champ3(); else{ fonction_champ1()} if (ligne[i]==1) fonction_champ3();
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:
Si les sont peu utiliser c'est qu'ils sont facilement remplassable.
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; }
Là par contre, en effet, je trouve déjà l'utilisation du goto risquée... Très risquée...Envoyé par ulukahio
Plutôt d'accord avec les propositions des deux posts au-dessus de celui-ci...
Partager