MQL5で配列を関数の戻り値にする方法 – 関数への値渡しと参照渡し –

2021/07/08

検証
配列を関数の戻り値に

はじめに

MT5のEA作成言語MQL5で配列を関数の戻り値とする方法を説明します。
その際、戻り値の配列サイズも動的に変更できるようにします。

今回確認すべき内容は

  • 関数への値渡しと参照渡し
  • 配列の動的サイズ指定

の2点です。

厳密には配列を関数の戻り値とすることができません。そのため参照渡しを使って配列に値を格納します。

サンプルコードを用いて説明していきます。

値渡しと参照渡し

関数に値を渡す方法は2つあります。

  1. 値渡し
  2. 参照渡し

値渡しは以下のコードのように値を直接渡すものです。

int OnInit()
  {
   double a = 5;
   double b = 3;
   double c = add_function(a, b);
   printf(c);// -> 8.0
   printf(a);// -> 5.0
   return(INIT_SUCCEEDED);
  }
double add_function(double a, double b)
  {
   a = a + b;
   return a;
  }

add_function内部でaをa+b(=5+3=8)と書き換えています。ただ、値を渡しているだけなのでaは関数実行後は書き変わりません。
そのため、aは実行後も5のままです。

一方の参照渡しは引数のところに&を書きます。

int OnInit()
  {
   double a = 5;
   double b = 3;
   double c = add_function(a, b);
   printf(c);// -> 8.0
   printf(a);// -> 8.0
   return(INIT_SUCCEEDED);
  }
double add_function(double &a, double b)
  {
   a = a + b;
   return a;
  }

関数内部にaが値としてではなく、aそのものが渡されるので、関数実行後、aは8になります。

これを利用して、配列に値を格納します。

参照渡しで配列に格納

配列は[]をつけます。参照渡しで配列を引数とするので、&array[] となります。

そして、関数自体の戻り値はない(不要)なので、voidとして関数を定義します。

int OnInit()
  {
   double array[] = {1,2,3,4,5};
   array_test(array,2);
   ArrayPrint(array);// -> 2.000  4.000  6.000  8.000  10.000
   return(INIT_SUCCEEDED);
  }
void array_test(double &array[], double times){
   int size = ArraySize(array);
   for(int i=0;i<size;i++){
      array[i]=array[i]*times;
   }
}

配列をプリントする際、通常のprintfではプリントができないため、ArrayPrintが便利です。もちろんforループを使って要素を一つずつプリントすることで確認もできます。

このサンプルでは最初に関数のサイズ(5)を決定していました。
次は関数内部で配列のサイズが変更される場合は動的配列を使って関数内でサイズを変更できるようにします。

動的配列

動的配列は配列定義時にサイズを指定しません。double array[]; とすることで動的配列として定義できます。

array_test2関数内部で、ArrayResize 関数を使用してサイズを定義しています。

関数の処理に応じてサイズをこのように変更して使いましょう。

int OnInit()
  {
   double array1[];
   double array2[];
   array_test2(array1,3);
   array_test2(array2,5);
   ArrayPrint(array1);// -> 0.000 1.000 4.000
   ArrayPrint(array2);// -> 0.000 1.000 4.000 9.000 16.000
   return(INIT_SUCCEEDED);
  }
void array_test2(double &array[], double times){
   ArrayResize(array,times);
   for(int i=0;i<times;i++){
      array[i]=i*i;
   }
}

まとめ

配列を直接関数の戻り値とすることはできません。

そのため配列を関数の手前で定義して、参照渡しによって値を書き込みます。

strのプロフィール画像

str