関数への参照渡し

関数への引数の渡し方

関数を上手に利用することで、プログラムの処理をカプセル化して処理を再利用しやすくし、コードの可読性を上げることができます。MQL4も当然ながら標準関数だけでなく自作関数も利用することができますね。

今回は、その関数に渡す引数のお話です。

引数の値渡し

intやstring、datetimeなどの基本データ型はシンプルに「値渡し」ができます。MQL4の標準関数で名前が長いものは短縮させるためにこんな関数も作ってコーディングしています。多少のオーバーヘッドは出るでしょうけど。例えばこんなコード。

// 関数
string D2S(double ArgPrice)
{
   return(Double2Str(ArgPrice, Digits));
}

// 価格を文字列にしたい
string sprice = D2S(Ask);

上の例では、単純に「価格」というdouble型の「値」を関数に渡して、string型になった価格の文字列を「値」として取得しています。また、一度渡された引数が関数のなかで書き換えられてしまったとしても、関数の呼び出し元が持っている引数に使った変数は値は書き換えられません。

では、配列や構造体の場合はどうでしょうか。この場合は「参照渡し」という方法が必要です。

引数の参照渡し

下の例では、初めにチャートの「バー」を意味する構造体「StructBar」という器を定義しています。構造体は内部に定義した変数を組み込んで、意味を持ったデータの塊(構造)を作ることができる仕組みです。構造体は変数の一つとして扱うことができ、配列と同様に一つの変数の中に複数の値を持っています。(厳密には表現は正しくないでしょうが、ざっくりと)

続いて、その構造体に「バー」の情報をセットする関数「SetStructBar」を定義しています。コードとしては、右辺から左辺に代入をしているだけですが、データ「バー」としては日時の情報、始値、終値、高値、安値、、、などの「バー」として成り立つための要素が複数あります。

この構造体「バー」の情報を埋めるためには上に書いた情報を一つひとつ取得していかなければなりませんが、それらはただの一行のコードだとしても実体は「バー」という意味を持っています。だから、バーを作り出す処理は関数の中にひとまとめにしたほうがコードの中で再利用もしやすく、間違いがありません。

// 構造体
Struct StructBar stbar
{
   datetime opendt;
   datetime closedt;
   double open;
   double close;
   double high;
   double low;
}

// 構造体に特定のバーの情報をセット
void SetStructBar(int ArgShift, StructBar &ArgStBar)
{
   ArgStBar.opendt = Time[1];
   ArgStBar.close = Close[1];
   // あとは割愛
}

// 構造体に一つ前のバーの情報をセット
SetStructBar(1, stbar);
Print(stbar.close);

で、この関数「SetStructBar」の第二引数に「&」がついているのがお分かりかと思います。これは「参照渡し」を意味しています。

この「参照渡し」とは、値そのものを関数に渡しているのではなく、値が入った器を渡しているようなイメージです。ただ、器を持ち歩くのではなくて、「器はここに置いてありますよ」の情報が渡されます。MQL4では配列や構造体は、この「参照渡し」をしなければならないルールになっているので、「参照渡し」で引数を渡した関数の呼び出し元と、引数を渡された関数は「同じ器」=「同じ変数」を見ていることになります。その結果、参照渡しで渡された関数側で値を変更すると、関数の呼び出し元でも変更の内容を参照することができるわけです。

Shareこの記事をシェアしよう!