Ramificação Condicional - 'GoTo' Kluge ? - página 4

 

Java também não está funcionando fora de sua máquina virtual, lá você terá os mesmos problemas, você não pode fazer uma dll que pode ser carregada e chamada a partir de um programa C.

Se você gosta do C# então você também gostará do ObjectPascal (o tipo de segurança, o rigor, toda a filosofia por trás dele, exceto a coisa da VM). Afinal, o designer e arquiteto chefe do C# é a mesma pessoa que uma vez criou o Turbo-Pascal e o Delphi (ObjectPascal) e ele brilha através dele. Em alguns aspectos, o C# é como o ObjectPascal com a sintaxe C (feia, mas hoje em dia moderna).

Para interfacear diretamente com a máquina e com C-APIs (como é necessário para MetaTrader) e ainda usando uma linguagem tão poderosa quanto C#, não há muitas alternativas ao ObjectPascal. Alguns dizem que o C++ é igualmente poderoso (e pode também ser usado no lugar de OP), mas claramente não é tão elegante, tem muitas inconsistências e é tão propenso a erros que somente verdadeiros especialistas podem realmente dominá-lo.

 
7bit:

.... o retorno dentro de uma função fará com que ela retorne ao lugar de onde a função foi chamada.

Esta é a distinção crucial 7bit: Estou falando em invocar uma função completamente diferente, subrotina ou mesmo código importado, subrotinas inteiras &/ou funções FORA de toda a função atual. Um exemplo conceitual:

Estou em uma função que acontece da linha 100 à linha 20, mas quero invocar algo que não se enquadra neste escopo. Talvez uma função totalmente diferente que esteja nas linhas 50 a 60. <=-Isso não se encaixa nos parâmetros e exemplo acima, que é o que estou perguntando sobre É um substituto 100% do antigo gosub/retorno e, adicionalmente, a função permite passar valores e retornar valores.

Você PODE ter múltiplas declarações de retorno dentro da mesma função e também pode romper os loops com quebra ....

Entendido

Mas continuo sendo informado sobre como posso me mover dentro do escopo de uma função específica, o que eu entendo. Mas NÃO é sobre isso que estou perguntando e afirmei no início de tudo isso.

Quanto a 'exceções', então acho que você pode chamá-las assim, se desejar. Como afirmei, estou tentando encontrar um "trabalho ao redor" para acrescentar e utilizar a funcionalidade de funções como, por exemplo: GoTo, GoSub (fora da função CURRENT) etc. que não existe como uma função diretamente dentro da MQL4. Por suas respostas, a maioria de vocês conhece e compreende estas distinções de programação, mas não estão abordando a pergunta realmente feita.

 

FourX:

Estou em uma função que ocorre da linha 100 à linha 20, mas quero invocar algo que não se enquadra neste escopo. Talvez uma função totalmente diferente, que se situa nas linhas 50 a 60.
Crie uma função separada contendo o código das linhas 50 a 60, então você pode invocá-la de qualquer outra função em que estiver a qualquer momento.
 

considere isto:

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();
}

O que vai acontecer agora? Vamos começar com main(), vou explicar todas as etapas durante a execução (os comentários estão em verde, as instruções estão em preto):

  • (estamos na primeira linha em main())
  • empurrar o endereço de retorno para a pilha (precisa de 4 bytes), este é o endereço onde ele continuará uma vez que a chamada para foo() esteja concluída (precisamos lembrar disso para que mais tarde saibamos para onde voltar)
  • pular para a primeira linha de foo()
  • empurrar 4 bytes para a pilha para criar espaço para a variável local x
  • empurrar 4 bytes para a pilha para criar espaço para a variável local y
  • (nossa pilha agora é de 12 bytes de altura)
  • escrever o valor longo 33 aos bytes 0,1,2,3 (contado do topo da pilha)
  • escrever o valor longo 42 aos bytes 4,5,6,7 (contado do topo da pilha)
  • imprimir o valor longo que se encontra nos bytes 4,5,6,7 (contado a partir do topo da pilha)
  • estourar 4 bytes da pilha e esquecê-los (y sai fora do escopo)
  • estourar 4 bytes da pilha e esquecê-los (x sai do escopo)
  • pop 4 bytes da pilha, este é agora o endereço de onde viemos quando chamamos foo(), o endereço de retorno, pular para este endereço
  • (agora estamos de volta à linha principal() na próxima linha, aquela com bar())
  • empurrar o endereço de retorno (4 bytes) para a pilha
  • pular para a primeira linha de bar()
  • empurrar 4 bytes (variável local x) para a pilha
  • (nossa pilha agora tem 8 bytes de altura)
  • escrever o valor longo 5 aos bytes 0,1,2,3 (contado do topo da pilha)
  • saltar para o rótulo .LABELFOO
  • (agora observe cuidadosamente como tudo dá horrivelmente errado a partir daqui. Já sabemos o que todas as linhas a seguir farão porque eu expliquei acima, eles fazem exatamente as mesmas coisas que faziam antes, todos eles se comportam como se tivessem os 12 bytes superiores da pilha à sua disposição. Mas a pilha tem apenas 8 bytes desta vez! A próxima linha espera uma variável na posição 4,5,6,7 do topo da pilha, agora vamos ver o que acontece, aí vem a linha com a impressão)
  • imprimir o valor longo que se encontra nos bytes 4,5,6,7 (contado a partir do topo da pilha)
  • (oops? este não é o nosso x, este é o valor de retorno, a pilha tem apenas 8 bytes de altura desta vez, imprimindo um número total sem sentido)
  • estourar 4 bytes da pilha e esquecê-los (isto seria "y sai do escopo", mas não é y, na verdade é o x da outra função)
  • pop 4 bytes da pilha e esquecê-los (isto seria "x sai do escopo" mas não é x, acabamos de jogar fora o endereço de retorno!)
  • (a pilha está vazia agora!)
  • estourar 4 bytes da pilha para obter o endereço de retorno -> crash!

Você consegue ver? a função foo precisa de uma estrutura de pilha local de 8 bytes mais o endereço de retorno e a função bar apenas 4 bytes mais o endereço de retorno. Suas declarações de retorno já foram incorporadas pelo compilador em tempo de compilação, eles populam quantidades diferentes de bytes da pilha, você não pode usar um retorno para fazer o trabalho do outro, cada um funciona apenas para a função para a qual foi compilado.

Estes antigos idiomas que tinham GOTO em todo o programa não tinham escopo variável local e a única coisa que você tinha que acertar era igualar o número de GOSUB e RETURN para ser igual, todos os seus retornos só apareciam com o endereço de retorno e nada mais, todos os retornos se comportavam exatamente da mesma forma. Mas agora temos muitos "GOSUB "s de tamanhos diferentes (cada um empurra quantidades diferentes para a pilha) e também muitos retornos diferentes que populam quantidades diferentes da pilha. E temos variáveis locais na pilha. Isto simplesmente não pode funcionar, não importa as loucuras que você tente construir no compilador.

Você poderia teoricamente GOTO dentro da função *same* (e algumas linguagens permitem isto), mas você não pode me mostrar um código onde isto realmente levaria a um código mais elegante e mais fácil de entender e mais fácil de manter do que uma programação estruturada adequada. Tudo o que ele faria seria produzir uma confusão horrível. Ninguém precisa disto, portanto não é implementado.

 

Todos nós já sabemos que a MQL4 não tem funções nativas como um GoTo OU um 'GoSub -=> ReturnFromGoSub'. Não há nenhuma disputa sobre isso. Isto agora se tornou em repetidas explicações e exemplos do fato de que a MQL4 não tem tais funções nativas. Não há discussão a respeito. Não é disso que se trata este tópico e nunca foi. Então, podemos por favor parar de discutir sobre o que já sabemos e concordar?

Sabemos que estas são funções válidas em outras linguagens de programação e podem ser muito úteis.

O objetivo disto é descobrir SE pudermos simular e utilizá-las com o que está disponível na MQL4?

Por exemplo, uma conclusão válida da função do segundo caso na primeira frase de'GoSub -=> ReturnFromGoSub ' seria para: Retornar ao ponto do programa que o GoSub foi chamado e retornar os valores do GoSub para o ponto de chamada no programa.

 
FourX:

Por exemplo, uma conclusão válida da função do segundo caso na primeira frase de'GoSub -=> ReturnFromGoSub ' seria para: Retornar ao ponto do programa que o GoSub foi chamado e retornar os valores do GoSub para o ponto de chamada no programa.


Foi-lhe dito repetidamente que o que você está descrevendo é uma Função Personalizada . . por que você não pode aceitar isso ? por favor, dê um exemplo, com pseudo código, de porque uma Função Personalizada!= Gosub + Return
 

FourX:

'GoSub -=> ReturnFromGoSub ' seria para: Retornar ao ponto do programa que o GoSub foi chamado e retornar os valores do GoSub para o ponto de chamada no programa.

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
Lá você tem seus GOSUB e RETURN, embutidos diretamente na linguagem mql4, mesmo com argumentos passageiros e valores de retorno que não eram sequer possíveis no Commodore-BASIC ou qualquer outra linguagem antiga e aleijada com a qual você está constantemente tentando compará-la. Onde você esteve durante os últimos 30 anos?
 

FourX se você está aprendendo mql4 enquanto ainda tem sua mente ainda está na BBC Basic pensar defproc e proc e esquecer GoTo e GoSub.

Eu tinha uma micro BBC no início dos anos 80 ....ahhhh ainda me lembro das alegrias de tentar conseguir programas para carregar sua unidade de fita cassete :( nós costumávamos escrever programas na BBC Basic

 
SDC:

FourX se você está aprendendo mql4 enquanto ainda tem sua mente ainda está na BBC Basic pensar defproc e proc e esquecer GoTo e GoSub.

Eu tinha uma micro BBC no início dos anos 80 ....ahhhh ainda me lembro das alegrias de tentar conseguir programas para carregar sua unidade de fita cassete :( nós costumávamos escrever programas na BBC Basic

LOL . . . Eu tinha um Acorn Electron . . . quando estava quente não lia coisas da fita adesiva que eu tinha escrito quando estava frio e o visto versa . . . esses eram os dias. ;-)
 
RaptorUK:
LOL . . . Eu tinha um Acorn Electron . . . quando estava quente não lia coisas da fita adesiva que eu tinha escrito quando estava frio e o visto versa . . . esses eram os dias. ;-)

Sim, eram os dias certos :) torcendo uma chave de fenda dobrada naquele pequeno parafuso pelas cabeças da fita, enquanto batia repetidamente na lateral da fita haha