'条件分岐 - 'GoTo' Kluge ? - ページ 4

 

Javaは仮想マシンの 外では動作しないので、Cプログラムからロードして呼び出すことができるDLLを作ることはできません。

C#が好きなら、ObjectPascalも好きになるでしょう(型安全性、厳密性、VMのことを除けば、その背後にある哲学全体が好きなのです)。C#の設計者とチーフアーキテクトは、かつてTurbo-PascalとDelphi(ObjectPascal)を作った人と同じで、それがよく表れているのです。C#は、ObjectPascalにC言語の文法を取り入れたようなものです(不格好ですが、最近では流行しています)。

マシンやC-API(MetaTraderに必要)と直接連動し、かつC#のような強力な言語を使用するには、ObjectPascalに代わるものは多くありません。C++も同様に強力だと言う人もいますが(もちろんOPの代わりに使うこともできます)、明らかにエレガントではなく、多くの矛盾があり、エラーが起こりやすいので、真の専門家だけが真に使いこなすことができる言語と言えます。

 
7bit:

......関数内のreturnは、その関数が呼ばれた場所に戻るようにします。

ここが重要な違いです。私が言っているのは、全く別の関数、サブルーチン、あるいはインポートされたコード、サブルーチン全体、あるいは関数を、現在の関数全体の外側から呼び出すということです。概念的な例です。

例えば、100行目から20行目までの関数の中で、そのスコープの外側にあるものを呼び出したい。 <=-This doesn't fit the parameters and exampleabove which is what I am asking about これは古いgosub/returnの100%置き換えで、さらにこの関数は値を渡したり値を返したりすることができます。

同じ関数内で複数のreturnステートメントを持つことができますし、breakでループから 抜け出すこともできます ....

なるほど

しかし、私は、特定の関数の範囲内で 移動することができる方法について言われ続け、私はそれを理解しています。しかし、これは私が質問していること ではありませんし、このすべての開始時に述べたことです。

例外」については、あなたがそう呼びたいのなら、そう呼べばいいのでしょう。 私が述べたように、私は、以下のような機能を追加して利用するための「回避策」を見つけようとしているのです。GoTo、GoSub(CURRENT関数の外側)等、MQL4内に直接関数として存在しない機能を追加し、利用するための「回避策」を見つけようとしています。 皆さんの回答から、ほとんどの方がこれらのプログラミングの違いを知っており、理解しているようですが、実際に質問されたことには触れていないようです。

 

FourX:

100行目から20行目までの関数の中にいるのですが、このスコープの外側にあるものを呼び出したいのです。たとえば、50行目から60行目までのまったく別の関数を呼び出したい。
50行目から60行目までのコードを含む別の関数を 作成し、あなたがいる他の関数からいつでもそれを呼び出すことができます。
 

を考えてみてください。

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

さて、何が起こるでしょうか?まずmain()から始めましょう。実行中のすべてのステップを説明します(コメントは、命令は)。

  • (main()の最初の行にいます)
  • リターンアドレスをスタックにプッシュ(4バイト必要)、これはfoo()の呼び出しが終了した後に処理を続けるアドレスです(後でどこに戻ればいいのか分かるように、これを覚えておく必要があります)。
  • foo()の最初の行にジャンプする。
  • 4 バイトをスタックにプッシュし、ローカル変数 x 用のスペースを確保する
  • 4 バイトをスタックにプッシュして、ローカル変数 y の場所を空ける
  • (スタックの高さが12バイトになりました)
  • 長い値 33 を 0,1,2,3 バイトに書き込む (スタックの先頭から数えます)
  • 4,5,6,7 バイト(スタックの先頭から数えたもの)にロング値 42 を書き込む。
  • 4,5,6,7バイトにあるlong値を表示(スタックの先頭から数えたもの)
  • スタックから 4 バイトをポップし、それを忘れる (y がスコープの外に出る)
  • スタックから 4 バイトをポップし、それを忘れる (x はスコープ外になる)
  • このアドレスは、foo()を呼び出したときのリターンアドレスです。
  • (今は次の行の main() に戻っています。bar() がある行です。)
  • リターン・アドレス(4バイト)をスタックにプッシュする
  • bar() の最初の行にジャンプ
  • 4 バイト (ローカル変数 x) をスタックにプッシュします。
  • (スタックの高さが 8 バイトになりました)
  • 長い値 5 を 0,1,2,3 バイトに書き込む (スタックの先頭から数えます)
  • ラベル.LABELFOOにジャンプします。
  • (ここで、ここから先がどのように恐ろしくおかしくなっていくかを注意深く観察してください。以下のすべての行が何をするかは、上で説明したのでもうわかっています。これらの行は前とまったく同じことをし、スタックの上位 12 バイトを自由に使えるかのように振る舞います。しかし、今回のスタックは8バイトしかないのです次の行では、スタックの先頭から 4,5,6,7 番目の位置に変数があることを期待しています。)
  • スタックの先頭から数えて4,5,6,7バイト目にあるlong値をprintします。
  • (おっと、これは x ではなく、戻り値です。今回、スタックは 8 バイトしかないので、全く無意味な数字を表示しています)
  • スタックから4バイトをpopし、それを忘れる (これは「yが範囲外になった」ということですが、yではなく、実際には他の関数からのxです)
  • スタックから4バイトをpopして、それを忘れる(これは「xが範囲外になった」となりますが、xではなく、リターンアドレスを捨てただけです!)
  • (スタックは空っぽです)
  • スタックから 4 バイトをポップしてリターンアドレスを取得 → クラッシュ!

foo関数は8バイトとリターンアドレスからなるローカルスタックフレームを必要とし、bar関数は 4バイトとリターンアドレスしか必要としないことがわかります。これらの return 文は、コンパイル時にコンパイラによってすでに組み込まれており、スタックから異なる量のバイトをポップします。

プログラム全体にGOTOがあったこれらの古い言語では、ローカル変数のスコープがなく、GOSUBとRETURNの数を一致させることだけが正しくなければならず、すべてのリターンはリターンアドレスだけをポップし、他には何もしない、すべてのリターンはまったく同じ動作をしました。しかし、現在では、多くの異なるサイズの「GOSUB」(それぞれが異なる量をスタックにプッシュします)があり、また、多くの異なるリターンが異なる量をスタックからポップします。そして、スタックにはローカル変数があります。これでは、コンパイラにどんなおかしなものを組み込んでも、うまくいくはずがありません。

理論的には、同じ*関数内でGOTOすることは可能です(言語によっては可能です)が、それが適切な構造化プログラミングよりもエレガントで理解しやすく、保守しやすいコードにつながるようなコードを一つも見せてくれませんね。それは、ひどい混乱を生み出すだけです。誰もこれを必要としないので、実装されていないのです。

 

MQL4にはGoTo OR 'GoSub-=>ReturnFromGoSub'といったネイティブ関数がないことは、すでに周知の事実です。 そのことに異論はないだろう。MQL4にはそのようなネイティブ関数がないという事実の説明と例が繰り返されることになりました。 そこに議論はありません。 このスレッドはそういうものではありませんし、これまでもそうでした。ですから、私たちがすでに知っていて同意していることについて議論するのはやめていただけないでしょうか?

私たちは、これらの関数が他のプログラミング言語でも有効な関数であり、非常に有用であることを知っています。

このスレッドの要点は、MQL4で利用可能なものでそれらをシミュレートし利用することができるかどうかを調べることなのです。

例えば、「GoSub-=>ReturnFromGoSub」という最初の文の2番目のケースの有効な関数補完は、次のようになります。GoSubが呼び出されたプログラムのポイントに戻り、GoSubからプログラムの呼び出しポイント に値を返す。

 
FourX:

例えば、「GoSub-=>ReturnFromGoSub」という最初の文の2番目のケースの有効な関数補完は、次のようになる。GoSubが呼び出されたプログラムのポイントに戻り、GoSubからプログラムの呼び出しポイントに値を返す。


あなたは何度も、あなたの言っていることはカスタム関数 だと言われましたが、なぜそれを受け入れないのですか? なぜカスタム関数Gosub + Return なのか、疑似コードで例を挙げてください。
 

FourX:

'GoSub-=>ReturnFromGoSub'は、次のようになる。GoSubが呼び出されたプログラムのポイントに戻り、GoSubからプログラムの呼び出しポイントに値を返します。

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
GOSUBとRETURNが mql4言語には組み込まれている。この30年間、あなたはどこにいたのでしょうか?
 

もしあなたがmql4を学んでいる間、あなたの心はまだBBC Basicの中にあるのなら、defprocとprocを考えて、GoToとGoSubを忘れてください。

私は80年代初期にBBCマイクロを持っていました...ああ、私はまだそのカセットテープドライブからプログラムをロードさせようとする喜びを覚えています :( 我々はBBC Basicでプログラムを 書いたものでした。

 
SDC:

もしあなたがmql4を学んでいる間、あなたの心はまだBBC Basicの中にあるのなら、defprocとprocを考えて、GoToとGoSubは忘れてください。

私は80年代初期にBBCマイクロを持っていました...ああ、私はまだそのカセットテープドライブからプログラムをロードさせようとする喜びを覚えています :( 我々はBBC Basicでプログラムを書いたものでした。

笑).. . 私はAcorn Electronを持っていました ... それが暑かったとき、それは私が書いたテープからものを読まないでしょう それが寒かったとき、そしてその逆 ... それらは日でした ;-)
 
RaptorUK:
笑 .. .私はAcorn Electronを持っていました......それが熱かったとき、それは私が書いたテープからものを読まないでしょう、それが寒かったとき、そしてその逆......それらは日だった;-)

そう、あの頃はそうだったんだ :) テープヘッドのそばにある小さなネジに曲がったドライバーをねじ込みながら、その横を何度もトントンと叩いてね(笑)