今回は避けては通れない制御構造、if-else文による条件分岐処理について解説していきたいと思います。
今回作成するインジケーターは次のようなものです。
10行文字列を出力していますが、7~9行目は”Hello Indicator”を出力し、それ以外の行は”Hello MQL4″を出力しています。
・前々回作成した複数行の文字をチャートに出力するソース TestIndicator
今回は、前々回作成したソースの改造を通して学習して行きたいと思います。
以下は、前々回作成したfor文による繰り返し処理のstart関数です。
32 33 34 35 36 37 38 39 40 41 |
int start() { string moziretu = ""; for(int i = 0; i < 5; i++) { moziretu = moziretu + "Hello MQL4\n"; } Comment(moziretu); return(0); } |
まずは、同じ文字列を5行ではなく10行出力するように修正してみましょう。出来ればご自分で考えてみて下さい。
以下は修正後のソースです。
32 33 34 35 36 37 38 39 40 41 |
int start() { string moziretu = ""; for(int i = 0; i < 10; i++) { moziretu = moziretu + "Hello MQL4\n"; } Comment(moziretu); return(0); } |
変更したのは35行目のみですね。これで10行”Hello MQL4″が出力されるようになりました。
次は早速if-else文の使い方です。
1 2 3 4 5 6 7 8 9 10 11 12 |
if(条件式1) { // 条件式1に当てはまった時の処理 } else if(条件式2) { // 条件式2に当てはまった時の処理 } else { // 条件式1にも条件式2にも当てはまらなかった時の処理 } |
最初のifから条件分岐が始まって、それに当てはまらなければelse ifの処理へ、それも当てはまらなければelseの処理が実行されます。
ただし、パターンはこれだけではありません。
“else if”がない場合もありますし、”else”がない場合もあり、さらに”else if”も”else”もない場合があります。ただし、”if”がない場合はありません。
if-else文は必ず”if”から始まりますが、”if”だけで終了するかもしれないし、”else if”が最後だったり”else”が最後かもしれないということです。言葉で言うより実際の例を出したほうがわかりやすいと思うので、ここでは生まれてくる赤ちゃんを例にしてみたいと思います。
1 2 3 4 5 6 7 8 |
if(生まれてくる赤ちゃんが男の子だった場合) { 名前を太郎と名付ける } else { 名前を花子と名付ける } |
この例では、もし男の子が生まれたら太郎と名付け、そうでなかった場合、すなわち女の子だった場合は花子と名付けるという処理です。
ここでは”else if”が出て来ませんでしたね。このように、最初の条件式(生まれてくる赤ちゃんが男の子だった場合)を満たさなかった場合は、必然的に女の子が生まれてくる場合しかありえないわけですから、単純に上の例のように書けるのです。
例えば以下のように書いても同じ処理となります。
1 2 3 4 5 6 7 8 |
if(生まれてくる赤ちゃんが男の子だった場合) { 名前を太郎と名付ける } else if(生まれてくる赤ちゃんが女の子だった場合) { 名前を花子と名付ける } |
ただし、この例のように二者択一の分岐処理の場合は、混乱を招くので”else if”ではなく”else”を使うべきです。そのほうがシンプルですし、後でソースを見た時にわかりやすいです。
次は別の例を示します。以下は”else if”が複数回出てくる分岐です。(赤ちゃんの体重自体に深い意味はありません。数字は適当です)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
if(生まれてくる赤ちゃんの体重が2000g未満だった場合) { Sサイズの服を買う } else if(生まれてくる赤ちゃんの体重が2000g以上、かつ3000g未満だった場合) { Mサイズの服を買う } else if(生まれてくる赤ちゃんの体重が3000g以上、かつ4000g未満だった場合) { Lサイズの服を買う } else { LLサイズの服を買う } |
生まれてくる赤ちゃんの体重によって、買う服のサイズを変更する処理の例です。これが最も複雑なif-else文となります。
複雑とは言ってもそれほど難しくはないと思いますがいかがでしょうか。
・”else if”は1回も出てこないかもしれないし複数回出てくるかもしれない。
・”else”は1回も出てこないかもしれないが、2回以上は出てこない。
ではif-else文を使用して、7行目のみを”Hello Indicator”と出力するように修正してみます。
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
int start() { string moziretu = ""; for(int i = 0; i < 10; i++) { if(i == 6) { moziretu = moziretu + "Hello Indicator\n"; } else { moziretu = moziretu + "Hello MQL4\n"; } } Comment(moziretu); return(0); } |
37行目のif文でカウンタ変数iが6なら、文字列変数”moziretu”の末尾に”Hello Indicator\n”を追加しています。1行目出力時はカウンタ変数iが0であるため、7行目出力時は”i==6″となることに注意。
ここで、突然”==”なんて記述が出て来ました。これは比較演算子と呼ばれるものの一つで、日本語に訳すと「等しかった場合」となります。”=”とよく似ていますが”=”は代入演算子ですので、全く意味が異なり、if-else文には使用出来ません。
比較演算子には次のようなものがあります。
演算子 | 例 | 説明 |
---|---|---|
> | A>B | AがBより大きい場合 |
< | A<B | AがBより小さい場合(未満とも言います) |
>= | A>=B | AがB以上の場合 |
<= | A<=B | AがB以下の場合 |
== | A==B | AがBと等しい場合 |
!= | A!=B | AがBと等しくない場合 |
以上のような比較演算子を使用してif-else文の条件式を作っていくのです。
ただし、条件式が複雑になると、比較演算子だけではif-else文の条件式を作ることはできません。
その場合には論理演算子というものを使用する必要があります。
なんだか小難しそうな感じがしますが、それほど難しくはありません。
例えば、先程の例で「生まれてくる赤ちゃんの体重が2000g以上、かつ3000g未満だった場合」というif文を作ろうとした場合、「体重が2000g以上」という条件式は作れますよね。また、「体重が3000g未満」という条件式は作れますよね。
しかし、そのどちらも満たすという意味の「かつ」の部分をどう表現して良いかわからないと思います。
この「かつ」というのが論理演算子というものなのです。
論理演算子には以下の様なものがあります。
演算子 | 例 | 説明 |
---|---|---|
! | !A | Aではない(否定:NOTと言います) |
&& | A && B | AかつB(論理積:ANDと言います) |
|| | A || B | AまたはB(論理和:ORと言います) |
最後の論理和(OR)の記号は馴染みがないかもしれません。通常の日本語キーボードなら、BackSpaceキーの左側のキーをShiftキーを押しながら押すと入力できます。それを2つ続けて入力したものです。
では実際に7,8,9行目も”Hello Indicator”と出力するソースです。
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
int start() { string moziretu = ""; for(int i = 0; i < 10; i++) { if(i == 6 || i == 7 || i == 8) { moziretu = moziretu + "Hello Indicator\n"; } else { moziretu = moziretu + "Hello MQL4\n"; } } Comment(moziretu); return(0); } |
先ほどと違うのは37行目のみです。このif文により7,8,9行目に”Hello Indicator”が出力されます。日本語で表現すると、「カウンタ変数iが6または7または8の場合」という条件式になります。
また、以下のように書き換えることもできます。
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
int start() { string moziretu = ""; for(int i = 0; i < 10; i++) { if(i >= 6 && i <= 8) { moziretu = moziretu + "Hello Indicator\n"; } else { moziretu = moziretu + "Hello MQL4\n"; } } Comment(moziretu); return(0); } |
先ほどと違うのは37行目のみです。今度は「カウンタ変数iが6以上かつ8以下の場合」という条件式ですね。結果は先ほどと全く同じになります。
ではどちらのif-else文の条件式のほうが良いのでしょうか?その答えは「今後どのような変更が必要となる可能性があるか」によって変わってきます。逆に、今後どのような変更があるかわからない場合はどちらでも良いとも言えます。
例えば、今は7~9行目だけ出力内容を変えているが、それが5~9行目になるかもしれないといった場合、”if(i >= 6 && i <= 8)”のほうが良いでしょう。
また、今は7~9行目だけ出力内容を変えているが、さらに2行目も出力内容が変わるかもしれないといった場合は”if(i == 6 || i == 7 || i == 8)”のほうが良いでしょうね。違いは連続性があるかどうか、ですね。
どちらにしても「こうでなければならない」ということはありません。ただ、出来る限り今後の変更が楽になるように、また、後で読んで意味や意図がわかりやすいように、ということを可能な限り考えて作っていくということを忘れないで下さい。
もちろん、はじめからうまくは行かないかもしれませんが、とにかく練習することでどんどん上達しますよ。頑張って行きましょう。