関数内で宣言された変数はローカル変数です。
ローカル変数のスコープは、ローカル変数が宣言された関数内の範囲に制限されています。
ローカル変数は、任意の
式の結果で
初期化する事が出来ます。
ローカル変数は対応する関数のメモリ領域に格納されます。
サンプルソース:
void sub_function() {
int local_int = 1;
}
変数の
スコープは、変数を呼ぶ事が出来るプログラムパートです。
ブロック(内部レベル)内で宣言された変数は、その
ブロックに
スコープを持っています。
ブロックスコープは変数の宣言で始まり、最後の右中括弧(})で終了します。
関数の引数も、
関数の先頭で宣言されたローカル変数と同様なブロックのスコープを持っています。
内部ブロックの識別子が、ネストされたまたは外部ブロックの
識別子と同じ名前の場合、
内部ブロックの処理が終了するまで、外部ブロックの識別子は隠されます。
これは内部ブロック実行中は、外部ブロックにある同じ名前の識別子の値では無く、
内部ブロックのローカル識別子を見る事を意味します。
static付きで宣言されたローカル変数は、プログラム開始から存在しているにも関わらずブロックのスコープを持っています。
外部ブロックで宣言したグローバル変数と、ローカル変数の名前が競合した場合、コンパイルエラーにはなりませんが、
"外部ブロック変数が隠れます"といった警告が出ます。
警告が発生するプログラムはあまり気分が良い物では無いので、グローバル変数とローカル変数は違う識別子を使用しましょう。
スタック
MQL4プログラムではスタックと呼ばれる特殊なメモリ領域が自動的に作成されます。
このメモリ領域はローカル関数の変数を格納する為に割り当てられる。
スタックは全ての関数に割り当てられる。
デフォルトのスタックサイズは256k-byteです。
#property stacksizeでスタックサイズを指示する事が出来ます。
静的ローカル変数は、スタックとは別に存在するstatic変数・
global変数が格納される領域に保存されます。
動的に作成された変数も、スタックから独立したメモリ領域を使用します。
各関数を呼び出すと、内部の非静的変数用のメモリはスタックに割り当てられます。
関数の処理終了後、メモリが解放されます。
最初の関数から第2の関数が呼ばれた場合、
第2関数の変数に必要なサイズのメモリを、空いているスタックメモリに割り当てます。
このように、内部関数を呼び出す場合、スタックメモリは各関数に順次占有されます。
これは関数が呼び出されている間メモリ不足に繋がる可能性があり、
メモリ不足になる状況をスタックオーバーフローと呼ばれます。
したがって、大きなローカルデータを使う時は、
関数に入る際に要求に合わせた必要なメモリを割り当てる動的変数(
new,
ArrayResize())を使用した方が良いです。
そして、関数終了時にメモリ解放(
delete,
ArrayFree())をさせます。