Branchement conditionnel - 'GoTo' Kluge ? - page 4

 

Java ne fonctionne pas non plus en dehors de sa machine virtuelle, ce qui pose les mêmes problèmes. Vous ne pouvez pas créer une dll qui peut être chargée et appelée à partir d'un programme C.

Si vous aimez C#, vous aimerez aussi ObjectPascal (la sécurité des types, la rigueur, toute la philosophie qui le sous-tend, à l'exception de la machine virtuelle). Après tout, le concepteur et l'architecte en chef de C# est la même personne qui a créé Turbo-Pascal et Delphi (ObjectPascal) et cela se voit. À certains égards, C# est comme ObjectPascal avec la syntaxe C (laide mais aujourd'hui à la mode).

Pour l'interfaçage direct avec la machine et avec les API-C (comme c'est le cas pour MetaTrader), tout en utilisant un langage aussi puissant que C#, il n'y a pas beaucoup d'alternatives à ObjectPascal. Certains disent que le C++ est tout aussi puissant (et peut bien sûr être utilisé à la place d'OP) mais il n'est clairement pas aussi élégant, présente de nombreuses incohérences et est tellement sujet aux erreurs que seuls les vrais experts peuvent vraiment le maîtriser.

 
7bit:

.... le retour à l'intérieur d'une fonction la fera revenir à l'endroit d'où la fonction a été appelée.

C'est la distinction cruciale 7bit : Je parle de l'invocation d'une fonction, d'une sous-routine ou même d'un code importé, de sous-routines et/ou de fonctions entières EXTERNES à la fonction courante. Un exemple conceptuel :

Je suis dans une fonction qui se déroule de la ligne 100 à la ligne 20, mais je veux invoquer quelque chose qui se situe en dehors de CETTE portée. Peut-être une fonction entièrement différente qui se trouve dans les lignes 50 à 60. <=-Cela ne correspond pas aux paramètres et à l'exemple ci-dessus qui est ce que je demande C'est un substitut à 100% de l'ancien gosub/return et en plus la fonction permet de passer des valeurs et de retourner des valeurs.

Vous pouvez avoir plusieurs déclarations de retour dans la même fonction et vous pouvez également sortir des boucles avec break .....

Compris

Mais on continue à me parler de la façon dont je peux me déplacer dans le cadre d'une fonction spécifique, ce que je comprends. Mais ce n'est PAS du tout ce que je demande et ce que j'ai dit au début de tout ceci.

Pour ce qui est des "exceptions", je suppose que vous pouvez les appeler ainsi si vous le souhaitez. Comme je l'ai dit, j'essaie de trouver un "contournement" pour ajouter et utiliser la fonctionnalité de fonctions telles que : GoTo, GoSub (en dehors de la fonction CURRENT) etc. qui n'existe pas en tant que fonction directement dans MQL4. D'après vos réponses, la plupart d'entre vous connaissent et comprennent ces distinctions de programmation, mais ne répondent pas à la question posée.

 

FourX:

Je suis dans une fonction qui se déroule de la ligne 100 à la ligne 20, mais je veux invoquer quelque chose qui se situe en dehors de CETTE portée. Peut-être une fonction entièrement différente qui se trouve dans les lignes 50 à 60.
Créez une fonction distincte contenant le code des lignes 50 à 60 et vous pourrez l'invoquer à tout moment à partir de n'importe quelle autre fonction dans laquelle vous vous trouvez.
 

considérez ceci :

void foo(){
  int x;
  int y;
  y = 33;
  x = 42;
  .LABELFOO
  print(x);
  return;
}

void bar(){
  int x;
  z = 5;
  GOTO .LABELFOO
}

void main(){ //<-- program starts here
  foo();
  bar();
}

Que va-t-il se passer maintenant ? Commençons par main(), je vais expliquer toutes les étapes de l'exécution (les commentaires sont en vert, les instructions en noir) :

  • (nous sommes à la première ligne de main())
  • pousse l'adresse de retour sur la pile (il faut 4 octets), c'est l'adresse où il continuera une fois que l'appel à foo() sera terminé (nous devons nous en souvenir pour savoir plus tard où retourner)
  • saut à la première ligne de foo()
  • pousser 4 octets sur la pile pour faire de la place à la variable locale x
  • pousse 4 octets sur la pile pour faire de la place à la variable locale y
  • (notre pile a maintenant une hauteur de 12 octets)
  • écrire la valeur longue 33 dans les octets 0,1,2,3 (en partant du haut de la pile)
  • écrire la valeur longue 42 dans les octets 4,5,6,7 (comptés à partir du haut de la pile)
  • imprimer la valeur longue qui se trouve dans les octets 4,5,6,7 (comptés depuis le haut de la pile)
  • sortir 4 octets de la pile et les oublier (y sort de la portée)
  • extraire 4 octets de la pile et les oublier (x sort du champ d'application)
  • extraire 4 octets de la pile, c'est maintenant l'adresse d'où nous venons en appelant foo(), l'adresse de retour, sauter à cette adresse
  • (maintenant nous sommes de retour dans main() à la ligne suivante, celle avec bar())
  • pousser l'adresse de retour (4 octets) sur la pile
  • saut à la première ligne de bar()
  • pousser 4 octets (variable locale x) sur la pile
  • (notre pile a maintenant 8 octets de haut)
  • écrit la valeur longue 5 dans les octets 0,1,2,3 (en partant du haut de la pile)
  • Sauter à l'étiquette .LABELFOO
  • (maintenant, observez attentivement comment tout se passe horriblement mal à partir de maintenant. Nous savons déjà ce que toutes les lignes suivantes vont faire car je l'ai expliqué plus haut, elles font exactement la même chose que précédemment, elles se comportent toutes comme si elles avaient les 12 premiers octets de la pile à leur disposition. Mais la pile n'a que 8 octets cette fois-ci ! La ligne suivante attend une variable à la position 4,5,6,7 du haut de la pile, voyons maintenant ce qui se passe, voici la ligne avec le print)
  • imprime la valeur longue qui se trouve dans les octets 4,5,6,7 (comptés depuis le haut de la pile).
  • (oops ? ce n'est pas notre x, c'est la valeur de retour, la pile n'a que 8 octets de haut cette fois, il imprime un nombre totalement absurde)
  • sortir 4 octets de la pile et les oublier (ce serait "y sort de la portée" mais ce n'est pas y, c'est en fait le x de l'autre fonction)
  • sortir 4 octets de la pile et les oublier (ce serait "x sort de la portée" mais ce n'est pas x, nous venons de jeter l'adresse de retour !)
  • (la pile est vide maintenant !)
  • sortir 4 octets de la pile pour récupérer l'adresse de retour -> crash !

La fonction foo a besoin d'un cadre de pile local de 8 octets plus l'adresse de retour et la fonction bar de seulement 4 octets plus l'adresse de retour. Leurs déclarations de retour ont déjà été intégrées par le compilateur au moment de la compilation, elles sortent différentes quantités d'octets de la pile, vous ne pouvez pas utiliser un retour pour faire le travail de l'autre, chacun ne fonctionne que pour la fonction pour laquelle il a été compilé.

Ces vieux langages qui avaient GOTO dans tout le programme n'avaient pas de portée de variable locale et la seule chose que vous deviez faire correctement était de faire correspondre le nombre de GOSUB et de RETURN, tous leurs retours ne faisaient qu'afficher l'adresse de retour et rien d'autre, tous les retours se comportaient exactement de la même façon. Mais maintenant nous avons beaucoup de "GOSUB" de tailles différentes (chacun d'entre eux pousse des quantités différentes sur la pile) et aussi beaucoup de retours différents qui font sortir des quantités différentes de la pile. Et nous avons des variables locales sur la pile. Cela ne peut tout simplement pas fonctionner, quelles que soient les folies que vous essayez d'intégrer dans le compilateur.

Vous pourriez théoriquement utiliser le GOTO dans la *même* fonction (et certains langages le permettent) mais vous ne pouvez pas me montrer un seul morceau de code où cela conduirait à un code plus élégant, plus facile à comprendre et plus facile à maintenir qu'une programmation structurée. Tout ce que cela ferait, c'est produire un horrible gâchis. Personne n'a besoin de cela, donc ce n'est pas implémenté.

 

Nous savons tous que MQL4 ne dispose pas de fonctions natives telles que GoTo ou 'GoSub -=> ReturnFromGoSub'. Il n'y a aucun doute là-dessus. Cela s'est maintenant transformé en explications et exemples répétés du fait que MQL4 n'a pas de telles fonctions natives. Il n'y a pas d'argument là-dessus. Ce n'est pas le sujet de ce fil de discussion et ça ne l'a jamais été. Pouvons-nous arrêter de discuter de ce que nous savons déjà et sur lequel nous sommes d'accord ?

Nous savons que ces fonctions sont valables dans d'autres langages de programmation et qu'elles peuvent être très utiles.

Le but de cette discussion est de savoir SI nous pouvons les simuler et les utiliser avec ce qui est disponible dans MQL4 ?

Par exemple, une fonction valide pour compléter le deuxième cas de la première phrase de'GoSub -=> ReturnFromGoSub ' serait la suivante : Retourner au point du programme où le GoSub a été appelé et retourner les valeurs du GoSub au point d'appel dans le programme.

 
FourX:

Par exemple, une fonction valide pour compléter le deuxième cas de la première phrase'GoSub -=> ReturnFromGoSub ' serait la suivante : Retourner au point du programme où le GoSub a été appelé et retourner les valeurs du GoSub au point d'appel dans le programme.


On vous a dit à plusieurs reprises que ce que vous décrivez est une fonction personnalisée... pourquoi ne pouvez-vous pas l'accepter ? Veuillez donner un exemple, avec un pseudo-code, de la raison pour laquelle une fonction personnalisée!= Gosub + Return
 

FourX:

GoSub -=> ReturnFromGoSub ' serait pour : Retourner au point du programme où le GoSub a été appelé et retourner les valeurs du GoSub au point d'appel dans le programme.

double subtract_two_numbers(double a, double b){
  Print("will now calculate ", a, " minus ", b);
  return(a - b);                                 // <---- THIS IS YOUR RETURN
}

int start(){                                     // <---- PROGRAM STARTS HERE
  double s;
  double d;

  s = subtract_two_numbers(Ask, Bid);            // <---- THIS IS YOUR GOSUB
  d = subtract_two_numbers(Close[0], Open[0]);   // <---- THIS IS YOUR GOSUB

  Print("the spread is ", s);
  Print("price moved ", d, " since the open");
}                                                // <---- PROGRAM ENDS HERE
Voilà vos GOSUB et RETURN, intégrés directement dans le langage mql4, même en passant des arguments et des valeurs de retour, ce qui n'était même pas possible en Commodore-BASIC ou dans n'importe quel autre langage ancien et handicapé auquel vous essayez constamment de le comparer. Où étiez-vous au cours des 30 dernières années ?
 

FourX si vous apprenez mql4 alors que votre esprit est encore dans le BBC Basic pensez defproc et proc et oubliez GoTo et GoSub.

J'avais un micro BBC au début des années 80 ....ahhhh je me souviens encore des joies d'essayer de charger des programmes sur son lecteur de cassettes :( nous avions l'habitude d'écrire des programmes en BBC Basic.

 
SDC:

FourX si vous apprenez mql4 alors que votre esprit est encore dans le BBC Basic pensez defproc et proc et oubliez GoTo et GoSub.

J'avais un micro BBC au début des années 80 ....ahhhh je me souviens encore des joies d'essayer de charger des programmes sur son lecteur de cassettes :( nous avions l'habitude d'écrire des programmes en BBC Basic.

LOL . . . J'avais un Acorn Electron... quand il faisait chaud, il ne lisait pas ce que j'avais écrit sur la bande quand il faisait froid et vice versa... c'était l'époque. ;-)
 
RaptorUK:
LOL. . . J'avais un Acorn Electron... quand il faisait chaud, il ne lisait pas ce que j'avais écrit sur la bande quand il faisait froid et vice versa... c'était l'époque. ;-)

Oui, c'était l'époque, c'est vrai :) tourner un tournevis courbé sur cette petite vis à côté des têtes de bande tout en frappant répétitivement sur le côté de celle-ci haha