1
Bonjours tout le monde !

J'ai un petit souci : je suis en train de faire une petite intro pour un programme et je suis emmené a ouvrir souvent la même fenêtre avec la même animation ==> PROBLEME, je ne veux pas réécrire le code a chaque fois parceque ça prend trop de place je trouve, mais je veux a tout prix éviter les sous programme...

J'avais pensé a un Lbl avec a la fin un Goto conditionnel (if A=1 Then Goto 1 Else If A=2 Then Goto 2 ... Etc) Mais je trouve que ca prend trop de place aussi ...

Une idée ? happy
2
Pourquoi éviter à tout prix les sous-programmes ? tant qu'il n'y en a pas 10000, c'est supportable
Et les goto seraient la dernière chose à laquelle j'aurais pensé, c'est en général sale de mettre un goto dans un programme, à éviter, sauf pour les débutants ^^

3
beeen, j'aime pas les sous programmes... je trouve que ca casse tout, je fais un blocage la dessus ^^
4
a ben sinon il y a peu être un compromis : est-ce que je peux appeler un sous programme mais aller directement a une étiquette de celui ci ?

Si oui surtout dites le moi parceque ça serait vraiment mais alors vraiment super happy

Mais la pour l'instant la seule idée que j'ai trouvée, et que j'applique, ben c'est de faire passer une variable en paramètre (Z dans mon cas) et comme ça je peux regrouper plusieurs fonction dans un seul sous programme ^^ C'est pour le Zcontest en fait, je préfère qu'il n'y ai pas trop de sous programme !
5
en passant un argument dans Ans oui

enfin, un truc du genre :
prgmMAIN
Disp "blablabla"
1:prgmSUB
2:prgmSUB


prgmSUB
If Ans=1
Then
        Disp "HELLOW :)"
        Return
End

If Ans=2
Then
        Disp "lol"
        Return
End

...

Return


Ici, ça affiche "blablabla", puis "HELLOW smile" puis "lol"
6
a oui tiens ANS c'est la meilleur variable pour ça ^^ je l'oublie souvent celle la happy Bon ben merci je pense que c'est bien comme système !

Mais il me semble que il existe une instruction pour aller dans un sous programme a une étiquette donnée ... t'as jamais entendu parler ?
7
Il faut toujours essayer d'utiliser Ans, ça va plus vite, mais attention quand même, certaines fonctions modifient Ans (je ne fais pas la liste, mais ça serait intéressant de donner les faux amis).

Pour les labels conditionnels, on peut même s'amuser, s'il y a beaucoup de labels différents, à faire une recherche par dichotomie.
Je crois qu'on pourrait parler alors de "hard code" non ?
8
Baruch (./7) :
Je crois qu'on pourrait parler alors de "hard code" non ?


MOUAHAHA !! XD

Baruch (./7) :
Pour les labels conditionnels, on peut même s'amuser, s'il y a beaucoup de labels différents, à faire une recherche par dichotomie.


La par contre j'ai pas compris ^^
9
La recherche par dichotomie ?

Exemple :

On veut créer un code qui permet, suivant la variable A, d'aller au label correspondant. C'est donc un système de labels conditionnels.
A peut prendre les valeurs 1,2,3 et 4.

Recherche dans l'ordre :

If A=1
Goto 1
If A=2
Goto 2
If A=3
Then
Goto 3
Else
Goto 4
End


Le nombre moyen de tests avant d'aller au label est 2.25

Recherche par dichotomie :

If A<=2
Then

If A=1
Then
Goto 1
Else
Goto 2
End

Else

If A=3
Then
Goto 3
Else
Goto 4
End

End


Ici le nombre moyen de tests est 2.

Bien sûr, ce n'est pas toujours la meilleure solution. La recherche par dichotomie attribue pour chaque valeur de A le même nombre de tests. La recherche dans l'ordre attribue un nombre de tests variant, on peut donc l'utiliser si la fréquence d'utilisation des labels varie, en ordonnant les valeurs de A testées suivant leur fréquence d'utilisation.


A ouai okkk; pas con du tout, mais... vous avez prit des cours ? ^^ non parceque il y en a qui savent tellement de choses sur ce forum que je me pose la question quand même happy.

Ah et aussi j'ai du mal a comprendre comment tu a calculé le nombre de test moyen...
Baruch>bah ici, Ans est passé en argument, donc qu'il soit modifié dans le sous-programme, c'est pas très grave, au pire on peut le "sauvegarder" en le stockant dans une variable inutilisée ou dans une liste si on a plus de variables disponibles. Et je trouve cette solution mieux que le goto ^^
Euh j'ai pas tout compris tama, enfin ça a pas l'air méchant ^^.
skimman974 (./10) :
Ah et aussi j'ai du mal a comprendre comment tu a calculé le nombre de test moyen...


Simple, a chaque fois j'ai compté pour chaque label le nombre de tests a effectuer, puis j'ai divisé par 4 (puisqu'il y a 4 labels différents).
(300ème message yeah :cheekysmile

non, ce n'est pas méchant du tout, je dis juste que dans l'exemple que je citais au ./5, Ans est utilisé en tant qu'argument, et donc que le fait de le modifier à l'intérieur du sous-programme n'était pas grave, et que si on voulait l'utiliser plusieurs fois on pouvait sauvegarder sa valeur :

Ans->A
If Ans = 1
Then
...
End
If Ans = 2
Then
...
End

...


( ha il manque vraiment la belle feature du basic 68k de pouvoir utiliser des variables comme des constantes dans ce genre d'opération, ce qui permet de faire de merveilleux goto @label (si je me souviens de la syntaxe), et tellement plus encore .. )
Aaaah ben voila je me disais bien avoir entendu parler d'une telle instruction ! Mais pas pour ma caltosh XD tan pis, mais l'astuce de faire passer une variable en argument me convient, c'est plutôt pas mal.
c'était pas plutôt
Goto #label ? (# pour l'indirection)
[nosmile]Y'a bcp mieux je crois... =D

grinisp "MAIN PROGRAM
:For(L,-1,0:If L:Goto S:End
grinisp "MAIN AGAIN
:For(L,-1,0:If L:Goto S:End
grinisp "BACK IN MAIN
sorrytop
:Lbl S
grinisp "IN SUBROUTINE
:End
grinisp "N.B.

C'est un petit truc qui permet d'éviter d'avoir à préciser ou reprendre l'exécution. (Il n'y a qu'un label)
Et puis on pourrait presque compiler mécaniquement nos programmes comme ça...

Une autre version qui m'a été envoyé par Nitacku y'a longtemps:

grinisp "This is the first line of the program"
:stuff
:Goto A
:Lbl 1 This is the start of sub-program 1
:sub-program 1
:0 this 0 is an important flag. It always goes directly before the extra end.
:End <--this is the extra end
:Lbl A
:1 Let's begin the method of calling sub-program 1
:Repeat Ans
:If Ans
:Goto 1
:1
:End
:stuff the program will reach this point only after running the sub-program listed under Lbl 1

Voilà, après perso je trouve ça assez lourd à compiler, mais c'est le plus rapide, et flexible...

(pour d'autres infos sur le sujet: http://www.ticalc.org/archives/files/fileinfo/145/14542.html)
Wow, je suis impressioné, je n'avais jamais pensé à utiliser des "extra end".

Malgré tout, je n'arrive pas à comprendre l'utilité de ces programmes. Tu pourrais m'expliquer ?

J'arrive pas à suivre ton lien.


tama (./16) :
c'était pas plutôt Goto #label ? (# pour l'indirection)


si ( #souvenir lointain# )

gon33 (./17) :
assez lourd à compiler


??

Sinon pas mal les astuces (enfin le second je vois assez peu l'interêt, et le premier je trouve ça un peu lourd pour pas grand chose, mais bon cheeky )

[nosmile]
Bah, le second et le premier ça revient à la même chose...

C'est pour faire l'équivalent d'un "call" Asm:

Si je fais un Goto classique:

:Code1
:If condition: Goto A
:Code2
:Lbl A
:Sous-prog
:Disp "lol"


Le programme affiche "lol" alors que l'on veut revenir à Code2.

Avec un Goto double:

:Code1
:If condition: Goto A
:Lbl B
:Code2
:Lbl A
:Sous-prog
:Goto B
:Disp "lol"


Effectivement ça marche, mais que ce passe-t-il quand tu as besoin de ce sous prog à plusieurs endroits?

Pour chacun des appels, il faudrait faire un label (hyper lent, et long)

:Code1
:1=>K
:If condition1: Goto A
:Lbl B
:Code2
:
:2=>K
:If condition2: Goto A
:Lbl C
:Code2
:
:Lbl A
:Sous-prog
:If K=1:Goto A
:If K=2:Goto B
:Disp "lol"


Ici, le temps d'exécution et la longueur du code sont proportionnels au nombre d'appels du sous programme...

Maintenant, le code que je te propose est différent.
Quel que soit l'endroit d'où on l'appelle, il revient au bon endroit tout seul, et sans Goto, grâce à la boucle.


:Code1
:If condition1
:Then
:For(L,-1,0:If L:Goto S:End
:End
:
:Code2
:If condition2
:Then
:For(L,-1,0:If L:Goto S:End
:End
:
:Stop
:Lbl S
:Sous-prog
:End
:
:Eventuel sous-prog2




Baruch (./9) :
Recherche par dichotomie


Attention, si tu fais ça, ton code va planter (sauf chance).
Par exemple:

:While X = 45
:Code
:1=>A
:Goto A
:Lbl B
:45=>X
:End
:Disp "Lol"
:End
:
:Lbl A
:If A=1
:Then
:Goto B
:Else
:Goto C
:End


Ce code ne marche pas: il affiche "lol" à l'écran.
En effet, l'exécution ne rencontre jamais le dernier "End", car elle remonte au label B avant. Résultat, elle confond le premier End avec le second et "pense" que le if est finit quand elle le rencontre. Ce n'est que quand elle a affiché lol qu'elle termine le While.
Donc, il ne faut jamais mettre un Goto dans une boucle... (sauf exceptions)

D'ailleurs, la dichotomie c'est pas ça. Ce serait plutot:
(genre, j'ai A entre 1 et 4)

:If A<3
:Then
:if A<2
:Then
:Disp "A=1"
:Else
:Disp "A=2"
:End
:Else
:If A<4
:Then
:Disp "A=3"
:Else
:Disp "A=4"
:End
:End


Et voilà le lien tout beau^^
C'est une mine d'infos ce fichier, vous devriez le lire...
http://www.ticalc.org/archives/files/fileinfo/145/14542.html



Ok, merci pour cette longue réponse, j'ai compris à quoi sert ton code.


gon33 (./20) :
En effet, l'exécution ne rencontre jamais le dernier "End", car elle remonte au label B avant. Résultat, elle confond le premier End avec le second et "pense" que le if est finit quand elle le rencontre. Ce n'est que quand elle a affiché lol qu'elle termine le While.


Si quand même ça marche parcequ'ils utilisent une structure de pille pour les 'begin'-end (donc quand il voit un end il clos le derier truc ouvert recontré ) (mais par contre à trop faire ça sa ralentit à fond pasque ça garde en mémoire tous les trucs où il 'a pas atteint le end .. )

D'ailleurs heureusemet 99% des progs basic utiliset des if truc goto machin else goto truc end ou apparetés cheeky

grinisp "MAIN PROGRAM
:For(L,-1,0:If L:Goto S:End
grinisp "MAIN AGAIN
:For(L,-1,0:If L:Goto S:End
grinisp "BACK IN MAIN
sorrytop
:Lbl S
grinisp "IN SUBROUTINE
:End
grinisp "N.B.


Argggh des Goto dans des boucles, vive les erreurs de mémoire x_x

very (./22) :
Si quand même ça marche parcequ'ils utilisent une structure de pille pour les 'begin'-end (donc quand il voit un end il clos le derier truc ouvert recontré ) (mais par contre à trop faire ça sa ralentit à fond pasque ça garde en mémoire tous les trucs où il 'a pas atteint le end .. )

D'ailleurs heureusemet 99% des progs basic utiliset des if truc goto machin else goto truc end ou apparetés mod.gif


Ouaip, c'est bien ça.
Mais bcp de programmeurs Basic le font sans savoir que ça pose problème si tous les tests n'ont pas atteint leur fin.
Ben d'expérience si tu n'en abuses pas ca a l'air d'aller, ca rame vraiment dans les cas pathologique ( si c'est pas trop mal codé, en sortant du prog il supprime la pile restante de celui-ci .. ) [cas pathologiaues = grosse boucle où tu fais ca tout le temps dans tous les sens cheeky )
A ouaiiiii exelent ! Mais... pour une utilisation du style :

While Z

GROS CODE BIEN LONG

Goto Sub routine

GROS CODE BIEN LONG

Goto Sub routine

End

=> Si l'appel a la sous routine n'est pas conditionnel, c'est pas possible si ?
Si, bien sur que c'est possible. Tu fais la même chose mais sans "if" et "end" au bout. smile
a bon ?
mais je comprend pas... comment il sait à quel endroit revenir dans le code ?
Le 'end' après le code est prit pour le 'end' du for
tin jsuis dsl mais je comprend pas, dans mon exemple j'ai vraiment l'impression que ca va pas revenir au bon endroit...
A... ou alors je met le goto dans une condition toujours vrai ? genre

While (qqch)

GROS CODE SUPER LONG

If 1
Then
Goto A

GROS CODE SUPER LONG

If 1
Then
GOTO A

End (ca c'est le 'End' du 'While' qui est en haut)

Lbl A (routine)
CODE DE LA ROUTINE
End (donc celui la il ferme les conditions et du coup programme revient après le bon 'GOTO A' ??