ローカル変数

関数内で宣言された変数はローカル変数です。ローカル変数の有効範囲は、宣言された関数の内部に制限されています。ローカル変数は任意のの結果によって初期化出来ます。関数の全ての呼び出しは、ローカル変数を初期化します。ローカル変数は、対応する関数のメモリ領域に格納されます。

例:

int somefunc()
 {
  int ret_code=0;
  ...
  return(ret_code);
 }

変数の有効範囲とは変数を参照することが出来るプログラムの部分です。(内部レベルでの)ブロック内で宣言された変数の有効範囲はそのブロックです。ブロックスコープは、変数の宣言で始まり、最後の右中括弧で終了します。

関数の先頭で宣言されたローカル変数も関数パラメータ と同じくブロックの有効範囲を持っています。ブロックは変数の宣言を含むことが出来ます。ブロックが入り子にされ、外部ブロックの識別子が内部ブロック内の識別子と同名の場合、外部ブロックの識別子は、内部ブロックの動作が終わるまで隠されています。

例:

void OnStart()
 {
//---
  int i=5;     // 関数のローカル変数
    {
    int i=10; // 関数変数
    Print("Inside block i = ",i); // 結果は  i=10
    }
  Print("Outside block i = ",i); // 結果は  i=5
 }

これは、内部ブロックの実行中には、外部ブロックにおける同名の識別子の値ではなく、それ自身のローカルの識別子の値が見られることを意味します。

例:

void OnStart()
 {
//---
  int i=5;     // 関数のローカル変数
  for(int i=0;i<3;i++)
    Print("Inside for i = ",i);
  Print("Outside the block i = ",i);
 }
/* 実行結果
Inside for i = 0
Inside for i = 1
Inside for i = 2
Outside block i = 5
*/

static として宣言されたローカル変数は、プログラム開始時に存在しているにもかかわらず、有効範囲はブロックです。

スタック #

全ての MQL5 プログラムでは、自動的に作成されたローカル関数の変数を格納するために、スタックと呼ばれる特殊なメモリ領域が割り当てます。 One stack is allocated for all functions, its default size for indicators is equal to 1Mb. エキスパートアドバイザーとスクリプトでは、スタックサイズはスタックサイズをバイト単位で設定する#property stacksize コンパイラ指令を使用して管理することができ、デフォルトでは、 スタックのために8Mbのメモリが割り当てられます。

静的ローカル変数は、他の静的及びグローバル変数が格納されている、スタックとは別に存在する特殊なメモリ領域に保存されます。動的に作成された変数もスタックとは別のメモリ領域を使用します。

各関数呼び出し時に、内部の非静的変数にスタック内の場所が割り当てられます。メモリは関数の終了後に再使用出来るようになります。

1 番目の関数から 2 番目の関数が呼び出された場合、2 番目の関数は残りのスタックメモリから変数に必要なサイズを使用します。このように、付属の関数を使用する場合には、スタックメモリは順次各関数によって使用されます。これは、スタックオーバーフローと呼ばれる関数呼び出し中のメモリ不足につながる可能性があります。

従って、ローカルデータの量が大きい場合は動的メモリが使用されるべきです。関数に入る際に、ローカルに必要とされるメモリをシステムに割り当て(newArrayResize())、関数から出る際にメモリ解除します(deleteArrayFree())。

参照

データ型型のカプセル化と拡張性変数の初期化変数のアクセス権スコープとライフタイムオブジェクトの作成と解徐