※どの記事も、文章中に出てくる各用語については、なるべく関連記事のリンクを貼るようにしているので、講座記事を読み進めていく中で、「わからなくなってしまった」、「忘れてしまった」言葉が出てきたら、クリックして復習していただければと思います<m(__)m>
改めて前回の内容をおさらいをしておくと、
- 関数の外の部分をグローバル領域という。
ということをお伝えしました。
今回はグローバル変数についてお話ししたいと思います<m(__)m>
グローバル変数とは?
グローバル変数はローカル変数とは反対に、関数の外(=グローバル領域)に作られた(=宣言された)変数です。
//↓これはグローバル変数
int varGlobal;
void OnTick()
{
//↓これはローカル変数
int varLocal;
}
ここまではよろしいでしょうか?
問題は、グローバル変数とローカル変数、いったい何が違うのか?という点です。
端的に言えば、有効範囲(スコープ)が違います。
グローバル変数の有効範囲(スコープ)
ローカル変数の有効範囲が宣言した関数の中(宣言した{}の中)に限定されるのに対して、
グローバル変数の有効範囲はプログラム全体に及びます。
//int型のグローバル変数「varInt」を宣言
int varInt;
// void型の sampleFunctionを関数として宣言
void sampleFunction()
{
//グローバル変数「varInt」に値「5」を代入
varInt=5;
}
void OnStart()
{
//関数の呼び出し
sampleFunction();
//ログ出力
Print(varInt);
}
関数の外(グローバル領域)で、変数「varInt」を宣言した後、
自分で作ったsampleFunction関数の中でもも、OnStart関数の中でも、変数「varInt」が使えています。
コンパイルエラーも発生していません。
MQL5 Program Fileを実行してみると・・・
ログ出力も予想通りの結果です。
※上のサンプルコードですが、関数というのは呼び出して初めて作用するものです。
もしsampleFunction関数をOnStart関数内で呼び出さなかった場合はどうなるでしょう?
//int型のグローバル変数「varInt」を宣言
int varInt;
// void型の sampleFunctionを関数として宣言
void sampleFunction()
{
//グローバル変数「varInt」に値「5」を代入
varInt=5;
}
void OnStart()
{
//ログ出力
Print(varInt);
}
上のコードを実行してみると、
sampleFunction関数内にて「varInt」に5を代入しているはずなのに、ログ出力すると「0」になっていますね。
sampleFunction関数をOnStart関数内で呼び出していないので、「varInt」に5を代入する、という機能自体が作動していなかったんですね。
どんな便利な機械も、電源が入っていなければその役割を果たすことができないのと同じです。
同じ名前の変数名について その2
前回のローカル変数についての記事でも同じ変数名について書きました。
もう一度その内容をまとめると
- 大前提として、同じ{}ブロック内で同一の変数名をつけることはできない。
- 別々の関数内で宣言したローカル変数は同一の変数名をつけても文法的には問題がない。(ただし特別な意図がある場合を除いて、同じ変数を使うことは無用の混乱を招くので望ましいことではない)
ということでした。
今回はグローバル変数とローカル変数で同じ変数名だった場合の話をします。
結論から言うと、
グローバル変数とローカル変数の場合も、ローカル変数同士の場合と同様
同一の変数名をつけても文法的には問題がない。(ただし特別な意図がある場合を除いて、同じ変数を使うことは無用の混乱を招くので望ましいことではない)
ということになります。
具体的なコードで見ていきましょう
//int型のグローバル変数「varInt」を宣言
int varInt=3;
void OnStart()
{
//ログ出力
Print(varInt);
//結果は「3」が表示される
//int型のローカル変数「varInt」を宣言
int varInt=5;
//ログ出力
Print(varInt);
//結果は「5」が表示される
}
このファイルを実行すると、結果は↓のようになります
プログラムの処理は上から下に向けて記述されている順に行われる、という順次進行の原則に従って、最初はグローバル変数に代入した値「3」がログ出力されます。
ところが!
その直後、OnStart関数内のローカル変数として同名の変数が宣言された為、以降はローカル変数「varInt」が有効になり、2回目のPrint関数によるログ出力では「5」が出力された、という訳です。
上記のサンプルコードをコンパイルすると以下のような警告メッセージがでます。
※警告メッセージは、「望ましくない記述をプログラマーがしたとき」に発せられるものです。
コンパイルエラーが発生しているわけではありませんが推奨されない記述をしていることを意味しているので、いつ意図しない動作が発生するかわかりません。
基本的に修正して、警告メッセージは出なくするようにコードを記述していきましょう。
警告メッセージの意味は
「変数varIntの宣言が、グローバル変数を隠しています。前のvarInt宣言箇所を確認してください」
というものです。
コンパイルエラーがなくても、実質的にグローバル変数がプログラム内で無効化されてしまっています。
このような意図しない動作を招くのを防ぐため、変数名は常に重複しない(ユニーク)ものをつけるよう心がけましょう。
まとめ
今回はグローバル変数 について解説しました。
今回の記事では以下のことを学びました
- グローバル変数の有効範囲はプログラム全体に及ぶ。
今回は以上になります。
最後までお読みいただきありがとうございました<m(__)m>
コメント