mql5言語の特徴、微妙なニュアンスとテクニック - ページ 159

 
Yurixx:

教えてください、pls.

インジケータでは、ArraySetAsSeries()でclose[]などの系列の順番を一度設定するのか、それとも他の方法で設定するのでしょうか?

OnCalculate()またはOnInit()のどちらで行うのでしょうか?

戸惑う場面に遭遇したことがある。

最初のティックでAS_SERIESが設定したclose[]のオーダーが、次のティックで自然に通常のオーダー、つまり!AS_SERIESに変更される。

その理由は、コードに書かれていないのですが。

スカラー &arr[] を取得する関数では,配列のインデックスの 方向について絶対的な確信が持てない :-(

さらに、内部の「直列性」を変更すると、この方向は関数が終了した後も残ります...誰も期待していない副作用となります。

だから、残念ながら、関数に入力する配列を取得するときは、そのシリアライズを覚えておいて、便利なものに設定し、関数を終了するときは必ず元の配列を返してください。

これはOnCalculateのレアケースですが、実際には他のコードからも呼び出されることが多かったです。

 
Maxim Kuznetsov:

また、内部で「直列化」を変更した場合、関数が終了してもこの方向は変わらない...。

それを期待していたんです。そのため、初回ログイン時に一度だけ実行されるOnCalculate() ブロックにArraySetAsSeries(close,true)を記述しているのです。そして、この「連載」は確かに設定された。ところが、驚いたことに、2回目以降のティックでは、すでに「連続性」が逆になっていたのです。

マキシム・クズネツォフ

OnCalculateの場合はレアケースですが、実際には他のコードからもたまたま呼び出されました。

私はそのようなエキゾチックなものは持っていませんし、さらに、プログラム内部で時系列やバッファ配列の「直列化」を変更することもありません。そのため、インジケーターの最初に一度だけ設定すれば十分だと思います。しかし、これらの配列の「直列性」が保存されていることを確認できない場合、各サイクルのOnCalculate()の 最初に設定する必要があります。これは、まったく不自然なことのように思えます。

 
input string inStr = NULL; // Входная строка не может быть NULL, но об этом нигде не сообщается.

#define  PRINT(A) Print(#A + " = " + (string)(A));

void OnStart()
{
  string Str = NULL;
  
  PRINT(inStr == NULL); // false
  PRINT(Str == NULL);   // true


  PRINT(inStr == ""); // true
  PRINT(Str == "");   // false
}
コンパイル時に警告を発生させるのがよいでしょう。
 
fxsaber:
コンパイル時に警告を発生させるのがよいでしょう。

昔と何も変わっていなければ、NULL != "" 今までにも多くの人がこれに引っかかったことがある。

 
Alexey Viktorov:

昔と何も変わっていなければ、NULL != "" 今までにも多くの人がこれに引っかかったことがある。

そういう話ではないんです。

 
fxsaber:

私たちは別の話をしているのです。

そして、なぜそうできないのかを説明してください。なぜ

input string inStr = "";

かも知れませんが

input string inStr = NULL;

そんなはずはない

 
Alexey Viktorov:

そして、なぜそうできないのかを説明してください。

上のスクリプトはこれを示している。

 
fxsaber:

上のスクリプトはこれを示している。

そうであれば、何の疑問も抱かないはずです。周りの人は自分の心を読んでくれるはずだとか、自分よりプログラミングの訓練を受けているはずだとか、いつも思っているんですね。

 
Alexey Viktorov:

そうであれば、何の疑問も抱かないはずです。あなたはいつも、誰もが自分の心を読むべきだとか、自分よりプログラミングに長けているべきだと考えています。

この反応の理由がわからない。簡潔なコードは、この機能を100%実証しています。

 
fxsaber:

この反応の理由がわからない。簡潔なコードは、この機能を100%実証しています。

通常の反応です。あなたのコードが理解できません。説明を求めましたが、答えは...

NULLはそのような曖昧なものなので、慎重に扱う必要があります。特に文字列変数に適用した場合。

ドキュメントより

//--- если строка не инициализирована, то присвоим ей наше предопределенное значение 
if(some_string==NULL) some_string="empty";

したがって、この例では、NULLは文字列の長さが 0に等しいという意味ではなく、変数が初期化されていないことを意味します。

あなたの例では

input string inStr = NULL;

の場合、変数は初期化されます。どのように初期化されるのかがよくわからず、整理する気が起きない。

その結果

PRINT(inStr == NULL); // false

変数が初期化されていることを示す。繰り返しになりますが、何をもって、が大きな問題です。なぜ、NULLで変数を初期化することができないのでしょうか?

どうやらこの初期化によって、文字列の長さが0になるようで、このチェックでは

PRINT(inStr == ""); // true
理由: