# probleme avec la commande goto en language C



## J£$µ$ (2 Janvier 2005)

je fai un programme que je ne pe pa achever car je ne voi pa ou est l'erreur ,voici mon probleme:

if(X==pythagore) goto PYTHAGORE;


.....



      float MT,MO,...;
      printf("PYTHAGORE:  ");

......



merci de m'aider ...


----------



## Didier Guillion (2 Janvier 2005)

J£$µ$ a dit:
			
		

> je fai un programme que je ne pe pa achever car je ne voi pa ou est l'erreur ,voici mon probleme:
> 
> if(X==pythagore) goto PYTHAGORE;
> 
> ...



Bonjour,

Ne JAMAIS utiliser goto en C, est je pense, le meilleur conseil que je puisse te donner.

Cordialement


----------



## molgow (2 Janvier 2005)

Et dans n'importe quel langage autre que le C, le conseil est aussi valable 
Il n'est JAMAIS nécessaire d'utiliser un GOTO, on peut toujours faire autrement.

Pour ton problème, je ne vois pas où tu as déclaré un label PYTHAGORE ?!


----------



## J£$µ$ (2 Janvier 2005)

mais alor comment faire pour aller dans un programme?????

merci de m'avoir repondue!


----------



## Didier Guillion (3 Janvier 2005)

J£$µ$ a dit:
			
		

> mais alor comment faire pour aller dans un programme?????
> 
> merci de m'avoir repondue!



Bonjour,

Tu utilise un appel a une fonction, des "if else", etc. 
N'utilse jamais Goto et limite le "break" aux "switch-break".


Cordialement


----------



## alf_zorro (9 Janvier 2005)

arf, ce n'est pas si dramatique que ça les goto... regardez le code du kernel de OS X... y'en a un peu partout
et puis au final, ça ne change pas grand chose au code compilé. ça demande juste d'être rigoureux.


----------



## Didier Guillion (10 Janvier 2005)

alf_zorro a dit:
			
		

> arf, ce n'est pas si dramatique que ça les goto... regardez le code du kernel de OS X... y'en a un peu partout
> et puis au final, ça ne change pas grand chose au code compilé. ça demande juste d'être rigoureux.



Oui, t'a raison, et puis de toute facon les commentaires, ils y sont pas dans le code compilé alors à quoi ca sert d'en mettre ?


Cordialement


----------



## Luc G (10 Janvier 2005)

molgow a dit:
			
		

> Et dans n'importe quel langage autre que le C, le conseil est aussi valable
> Il n'est JAMAIS nécessaire d'utiliser un GOTO, on peut toujours faire autrement.



Pas tout à fait vrai, en Fortran II, III et même iV autant que je m'en souvienne, on était obligé de l'utiliser   Même chose sur le basic applesoft de l'apple II.   

Bon, ça nous rajeunit pas tout ça : en fait le goto est à l'informatique ce que la lampe à huile est à l'éclairage : ça fume, ça éclaire mal, ça peut foutre le feu, ceci dit, chacun ses goûts et ses risques.

PS. Depuis les débuts de l'ère de la programmation structurée, le GOTO est quasi- persona non grata, une des (très rares) exceptions étant  de permettre de sortir d'un programme rapidement et proprement (enfin, ça faut s'en occuper quand même). Le GOTO existe d'ailleurs, même en Pascal. Mais, durant mes années de programmation Pascal, je n'en ai jamais, je dis bien jamais, utilisé l'ombre d'un seul (pas plus que dans la suite d'ailleurs, mais comme j'ai peu programmé en C).


----------



## Luc G (10 Janvier 2005)

alf_zorro a dit:
			
		

> ça demande juste d'être rigoureux.



C'est là tout le problème : même avec la meilleure volonté du monde, on peut toujours faire des conneries, autant utiliser des constructions qui par nature t'en évitent certaines.


----------



## Ad_himself (10 Janvier 2005)

Pas faux.


----------



## Céroce (10 Janvier 2005)

Pour répondre à Jesus, il te faut créer une étiquette
PYTHAGORE:

à l'endroit où tu veux sauter.

Comme dit plus haut, c'est une très mauvaise habitude d'utiliser un goto. Je ne connais que deux cas intéressant d'utilisation:


for(compteur1 = 0; compteur1 <= 100000; compteur1++)
{
    for(compteur2 = 0; compteur2 <= 100000; compteur2++)
    {
         if( une condition )
               goto finBoucle;
    }
}

finBoucle:


Le goto est ici la meilleure solution (lisibilité, performances), autrement, il faut retester la condition dans la boucle de compteur1.


Autre cas: quand vous faîtes de la gestion d'erreur, vous sautez directement à la fin dès qu'une erreur apparaît.

Comme le conseille M. Kernighan, il faut par contre absolument éviter les goto pour sauter en arrière.


----------



## Didier Guillion (10 Janvier 2005)

Bonsoir,

Je suis d'accord Feroce, mais on aurait put aussi bien écrire les boucles imbriquées dans une fonction et placer un "return" au bon endroit.

Je me permet une remarque générale:
- Continuez a utiliser des "goto"
- Ne commentez pas vos sources
- Donnez des noms abscons a vos fonctions et variables

Comme on vous l'apprends a l'ecole, où l'on voit le C le Lundi, le C++ le Mardi, et le Java le Mercredi.
Et vous passerez à coté d'une des grandes joie, la **programmation** et deviendrez Chef de Projet ou Commercial. Avant de vous demander quel est le but de tout cela.

Cordialement


----------



## SuperCed (11 Janvier 2005)

Je suis d'accord avec Didier, les goto rende le code illisible.
Même pour un tout petit code, il ne faut pas prendre de mauvaises habitudes.

Je n'utilise JAMAIS le goto en C.
En fait à l'école, on en a même jamais parlé.

Pour les commentaires et les noms de fonctions, il faut essayé le plus possible d'être consistant et explicite.


----------



## Luc G (11 Janvier 2005)

Céroce a dit:
			
		

> Pour répondre à Jesus, il te faut créer une étiquette
> PYTHAGORE:
> 
> à l'endroit où tu veux sauter.
> ...



Ce sont effectivement les cas "justifiables". Encore doit-on noter que les langages se sont dotés la plupart du temps, d'abord d'instructions de type "exit" qui gèrent ça propement ; ensuite de traitement d'exceptions qui peuvent être utiles aussi.

En ce qui concerne la lisiblité (quand on n'a pas d'"exit"), ça peut être effectivement plus clair. En ce qui concerne les performances, ce serait à vérifier : ne jamais oublier que les compilateurs savent optimiser et ils peuvent être parfois d'une efficacité redoutable (pas toujours  ). Je me rappelle avoir fait, il y a bien longtemps des tests à ce niveau sur du fortran, c'était assez rigolo. Par exemple, on expliquait bien sûr qu'il valait mieux définir la valeur d'une variable qui n'avait plus à bouger avant une boucle plutôt que dedans. Mais en fait, au niveau du temps de calcul (et en fait du code compilé), c'était la même chose (faut dire que c'est pas très difficile à détecter). D'autres optimisations beaucoup plus tordues peuvent être effectuées par le compilo.


----------



## Céroce (11 Janvier 2005)

Je ne suis pas d'accord avec vous, dans le sens où il existe souvent UNE solution plus adaptée que toutes les autres à un problème donné.

Si j'évalue que le goto est la meilleure solution à mon problème (encore une fois, c'est rarement le cas), alors je l'utilise. Je ne vais pas m'en priver par _principe_.


----------



## Didier Guillion (11 Janvier 2005)

Céroce a dit:
			
		

> Je ne suis pas d'accord avec vous, dans le sens où il existe souvent UNE solution plus adaptée que toutes les autres à un problème donné.
> 
> Si j'évalue que le goto est la meilleure solution à mon problème (encore une fois, c'est rarement le cas), alors je l'utilise. Je ne vais pas m'en priver par _principe_.



Ce n'est pas un principe, c'est un conseil. 
Cela fait pas mal de temps que j'écrit du C tous les jours, 18 ans en fait, et je n'ai jamais trouvé de cas où son utilisation s'imposait. A mon avis, si le goto devient la seule solution, c'est que la structure de ta fonction est mauvaise.


Cordialement


----------



## flakk (12 Janvier 2005)

Didier Guillion a dit:
			
		

> Ce n'est pas un principe, c'est un conseil.
> Cela fait pas mal de temps que j'écrit du C tous les jours, 18 ans en fait, et je n'ai jamais trouvé de cas où son utilisation s'imposait. A mon avis, si le goto devient la seule solution, c'est que la structure de ta fonction est mauvaise.
> 
> 
> Cordialement


 entièrement d'accord... d'ailleur heureusement qu'il y a ce genre de post pour me rappeler que ca existe le goto  (ok, j'exagère un peu...)

 ca me rappelle les débats trollistiques sans fin sur usenet il y a quelques siècles... 
 du genre "Isn't #defining TRUE to be 1 dangerous, since any nonzero value is considered "true'' in C? What if a built-in logical or relational operator "returns'' something other than 1?"
 "Is it acceptable for one header file to #include another?" 
 ou encore ca: "Is the abbreviated pointer comparison "if(p)'' to test for non-null pointers valid? What if the internal representation for null pointers is nonzero?"

 avec les flame-wars qui s'en suivaient


----------



## alf_zorro (14 Janvier 2005)

Didier Guillion a dit:
			
		

> Oui, t'a raison, et puis de toute facon les commentaires, ils y sont pas dans le code compilé alors à quoi ca sert d'en mettre ?
> 
> 
> Cordialement



je sens que mon commentaire a été mal pris  
heuh moi non plus je n'utilise  jamais le goto, et même si j'ai 9 fois moins d'années d'expériences en C que toi, j'ai appris le C en lisant du code noyau, et force est de constater que ce goto est très présent les kernels!
et je suis tout à fait d'accord, il vaut mieux l'éviter, mais pour les gens qui ont commencé par l'assembleur, un goto ou un while,etc..., ça ne change pas grand chose, c'est "juste" une vue de l'esprit, enfin, à mon humble avis.

heuh, grosse parenthèse, en cherchant sur le web ton nom (des fois que tu aurais été un de mes profs à la fac ;-)), je suis tombé sur sapiens, c'est le même toi qui l'a fait?   parce que j'adorais ce jeu quand j'étais gamin!


----------



## Didier Guillion (15 Janvier 2005)

alf_zorro a dit:
			
		

> je sens que mon commentaire a été mal pris
> heuh moi non plus je n'utilise  jamais le goto, et même si j'ai 9 fois moins d'années d'expériences en C que toi, j'ai appris le C en lisant du code noyau, et force est de constater que ce goto est très présent les kernels!
> et je suis tout à fait d'accord, il vaut mieux l'éviter, mais pour les gens qui ont commencé par l'assembleur, un goto ou un while,etc..., ça ne change pas grand chose, c'est "juste" une vue de l'esprit, enfin, à mon humble avis.
> 
> heuh, grosse parenthèse, en cherchant sur le web ton nom (des fois que tu aurais été un de mes profs à la fac ;-)), je suis tombé sur sapiens, c'est le même toi qui l'a fait?   parce que j'adorais ce jeu quand j'étais gamin!



Bonjour,

Cela veut peut etre dire que les Kernels ne sont pas tous bien écrit...
Oui, je suis l'auteur de Sapiens, écrit en 6809 sur les Thomsons, reecrit en Z80 pour Amstrad , puis 68000 et C pour la version Atari et enfin 8086 pour la version PC. Ouf !
A l'époque rien n'existait. Quand tu voulais programmer un jeu, tu commencait par t'écrire un assembleur en basic, puis tu reecrivait l'assembleur en assembleur pour que ca aille plus vite, et tu pouvait commencer ton jeu...

Cordialement


----------



## alf_zorro (15 Janvier 2005)

Didier Guillion a dit:
			
		

> Bonjour,
> 
> Cela veut peut etre dire que les Kernels ne sont pas tous bien écrit...
> Oui, je suis l'auteur de Sapiens, écrit en 6809 sur les Thomsons, reecrit en Z80 pour Amstrad , puis 68000 et C pour la version Atari et enfin 8086 pour la version PC. Ouf !
> ...



et bien merci pour les heures de jeu! et je comprends mieux pourquoi tu détestes les goto ;-)

j'ai trouvé un chtit exemple de goto dans OS X (dans posix_sem.c, gestion des sémaphores POSIX):


> AUDIT_ARG(text, pnbuf);
> if (pathlen > PSEMNAMLEN) {
> error = ENAMETOOLONG;
> goto bad;
> ...



et pourtant la norme comprenant les sémapgores POSIX date de plus ou moins 94!


----------



## ntx (15 Janvier 2005)

Bonjour,
on remarquera juste que dans l'exemple donné par alf_zorro, le "goto" semble être utilisé pour géré les erreurs, ce qui reste une utilisation très restreinte.
Et que pour cela, un petit code C++ utiliserait les exceptions ... et alors au revoir les "goto" 
Je rajouterais que les personnes qui ont été le noyau et les librairies POSIX étaient surement confronté à des problèmes de performances. Dans ce cas, le code généré par le compilateur est peut être meilleur en utilisant le "goto" plutôt que sans : il faudrait voir le code assembleur pour en être sur. Des amateurs pour essayé ? 

Pour ma part, je pense qu'on peut parfaitement s'en passer dans la vie de tous les jours (je programme en C/c++ depuis plus de 10 ans et je n'ai jamais mis de "goto" dans un de mes programmes) mais peut être que dans des cas très précis ???

PS : dans l'exemple de Ceroce, si le "for" doit être interrompu, alors peut être vaut-il mieux le remplacer par un "while" avec un test sur un flag, non ?


----------



## Céroce (17 Janvier 2005)

ntx a dit:
			
		

> PS : dans l'exemple de Ceroce, si le "for" doit être interrompu, alors peut être vaut-il mieux le remplacer par un "while" avec un test sur un flag, non ?



Il faut faire ce qui te semble le plus lisible. Je ne crois pas qu'utiliser un while() soit une bonne solution; c'est bien une boucle for que tu souhaites faire, non ?

Pour se _passer_ du goto:



```
quitterBoucle = false;

for(compteur1 = 0; compteur1 <= 10000; compteur1++)
{
    for(compteur2 = 0; compteur2 <= 10000; compteur2++)
    {
         if(  condition   )
         {
             quitterBoucle = true; 
             break;
         }
    }

    if(quitterBoucle)
        break;
}
```

Je trouve ça plus lisible avec un goto, mais peut-être avez-vous une solution plus élégante à proposer ?   

Cordialement,
Céroce


----------

