改めて前回の内容をおさらいをしておくと、
- while文と同様に、ループを終了させる条件記述が{}内になかったり、記述が適切でなかった場合、ループが終了せずに無限ループになってしまう可能性があるので記述には注意する。
ということをお伝えしました。
今回はfor文についてお話ししたいと思います。
for文とは?
for文は、
「繰り返し処理」命令をする記述の1つです。
do-while文の講座記事の時にも書きましたが、ループ処理させたい回数が決まっている場合や、
do-while文、while文よりも発展的なループ記述処理をさせたい時は、for文を使うとよいと思います。
実際、do-while文、while文でやれることは、for文でもやれることがほとんどなので、繰り返し処理においてはほとんどがfor文を使われている印象です。
for文の使い方
まずはfor文の文法的構造を見ていきましょう。
for(ループ継続の条件)
{
//ループ中に実行する処理
}
上記のような構造になっています。
forキーワードを記述した後、()内にループ継続の条件を記述し、{}内にループ中実行する処理の記述を行う。
冒頭に用いるキーワードがforに変わった以外は、while文と構造的には同じですね。
while文と違うところは、()内のループ継続条件の記述方法です。
for文の場合、()内に3つの記述セクションが設けられています。
for(セクション1;セクション2;セクション3)
↑のような形です。
セクション1とセクション2の間、セクション2とセクション3の間にはセミコロン(;)を入れて区切ります。
セクション1、セクション2、セクション3にはそれぞれ何を記述すればよいのでしょうか?
次はそれを見ていきましょう。
まずはセクション1から。
セクション1にはループをどの時点から始めるか、を記述する
セクション1にはループをどの時点から始めるか、をを記述します。
(このセクション1の部分を初期化式などと言ったりします)
for(ループをどの時点から始めるか;セクション2;セクション3)
{
}
ここには、ローカル変数を宣言して、そこにループの始点となる値を代入する記述をすることが多いです。変数名はもちろん、好きにつけてよいのですが、慣習的に、
ループ回数に用いる変数名には、慣習的にindex(索引、見出し)やiteration(繰り返し)などを意味する
i
が用いられることが多いです。
for(int i=1;セクション2;セクション3)
{
}
↑ これでループは「i」に代入されている値、すなわち「1」から始まる、という記述になります。
セクション2には、ループをどこで終了するか、を記述する
セクション2には、ループをどこで終了するか、を記述します
for(ループをどの時点から始めるか;ループをどこで終了するか;セクション3)
{
}
ループの始点と終点が決まります。すなわち、
「~から始まって、・・・までループする」
という記述になるわけです。
for(int i=1;i<=5;セクション3)
{
}
i<=5→(iの値が5より小さいか、5と等しいまで)ループを継続する
という意味になります。すなわち
1から始まり、5までループを継続するということですね。
セクション3には、{}内の処理が終わるごとに行う処理内容を記述する
セクション3には、{}内の処理が終わるごとに行う処理内容を記述します
for(ループをどの時点から始めるか;ループをどこで終了するか;{}内の処理が終わるごとに行う処理)
{
}
{}内の処理が終わるごとに行う処理内容は、インクリメントやデクリメントを使って、1回ループが終わるごとにループ変数である「i」の値を、漸増漸減させていく記述がほとんどです。
※インクリメントやデクリメントについてはコチラ
for(int i=1;i<=5;i++)
{
}
i++ すなわち
{}内の処理が終わるたびに、iの値を1づつ増やしていく(=インクリメント)という意味になります。
「1から5までループさせる。{}内の処理が終わるごとに、iの値を1づつ増やしていく」
このような意味になります。
void OnStart()
{
for(int i=1; i<=5; i++)
{
Print(i);//1,2,3,4,5がログ出力される
}
}
↑はiをインクリメントによって漸増させていくパターンです。
{}内のPrint(i);という処理がおわるごとに、iの値が1,2,3…と1づつ増えていきます
デクリメントの場合は・・・↓
void OnStart()
{
for(int i=5; i>=1; i--)
{
Print(i);//5,4,3,2,1がログ出力される
}
}
となります。
{}内のPrint(i);という処理がおわるごとに、iの値が5,4,3…と1づつ減っていきます(=デクリメント)
実際にMQL5 Program Fileをチャートに挿入して、挙動を見てみましょう。
最初が、インクリメントの場合、次がデクリメントの場合です。↓
それぞれ、「1,2,3,4,5」「5,4,3,2,1」という予想通りの結果がログ出力されました。
おまけ1 -ループ回数に用いる変数名について-
先ほど、
ループ回数に用いる変数名には、慣習的にindex(索引、見出し)やiteration(繰り返し)などを意味する
i
が用いられることが多い、と書きました。
ソースコードをほかの人に見せるときや、共同開発をすような時に、共通理解を得るのが早くなりやすい一方で、
i
一文字だけではエディタ内を検索しても、多数ヒットしてしまい、いかにも使い勝手が悪い!
という側面もあります。
個人的には、繰り返し構文であるというイメージが湧きやすい「i」を頭文字に使いつつ、例えば「iCounter」 「iLoop」などの、 1文字以上の変数名をつけるのが良いのではないかな、と考えています。
おまけ2 -()内の記述省略について-
for文の()内のセクション1~セクション3の記述は、実は省略することも可能です。
ただし、各セクションを区切るセミコロンは必ず記述する必要があります。
void OnStart()
{
for()
{
Print(i);//semicolon expectedというエラーが発生する
}
}
↑これはだめだけど・・・
void OnStart()
{
for(;;)
{
//コンパイルエラーは発生しない
}
}
↑これはコンパイルが通ります。
セクション2である、ループの終点を指定する記述がない場合、while文や do-while文でも書いてきたような無限ループが発生します。
void OnStart()
{
for(int i=0;;i++)
{
Print(i);//無限ループ発生
}
}
動画のような無限ループにしないために、
for文のセクション2で終点を指定しない場合は、{}内にループを離脱させるための記述を別途する必要があるでしょう。
いずれにしても、オマケ項目で書いていることからもわかる通り、セクション1~セクション3の記述のいずれかを省略することは特殊です。あまり使うことはないでしょう。
おまけ3 -セクション1とセクション3に複数の変数を設置-
これも、特殊な例だという前提で読んでほしいのですが、
セクション1(ループの始点を記述する部分)
と
セクション3({}内の処理が終わるごとに行う処理を記述する部分)に複数の変数を設置することができる、という例も紹介したいと思います。
void OnStart()
{
for(int a1=1,a2=2;a1<=5;a1++,a2+=2)
{
Print("a1=",a1,"a2=",a2);
}
}
a1=1 と a2=2
複数の変数を宣言する場合は、変数と変数の間にコンマを記述します。
セクション2のループ終点は
a1<=5 すなわち a1が5になるまでループする、とします。
セクション3の{}内処理終了後の処理記述に関しては、
a1++、すなわちa1を1づつ増加させる
a2+=2は a2+2と同じ意味ですから、すなわちa2を2づつ増加させる
という意味になります。
これをPrint関数でログ出力させると・・・
a1が「1,2,3,4,5」
a2が「2,4,6,8,10」
とログ出力される結果になりました。
まとめ
今回はfor文について解説しました。
今回の記事では以下のことを学びました。
- for文は、()内のループ継続条件の記述が(1) ループの始点を記述するセクション(2)ループの終点を記述するセクション(3) {}内処理終了ごとの処理を記述するセクション の3つのセクションに分かれる。
今回は以上になります。
最後までお読みいただきありがとうございました<m(__)m>
コメント