条件分岐文

条件分岐文を使用することで、変数に格納されている値や関数の戻り値などに応じて実行する命令を制御することが出来るようになります。
(一応定数も条件式に組み込めますが、それでは分岐できないのでかなり特殊な例ですね)




条件分岐概要

例えば、ここに250gりんごが1つあるとしましょう。このりんごを家族で分けるとして、均等にn分割します。
この時、素直に考えれば自分は「250(g) / n(人)」の量のりんごを食べることが出来ますよね。わからない人は算数からやり直せ。
さて、今話したことをKuinで記述すると以下のようになります。
  1. func Main()
  2. var Apple : float :: 250.0
  3. var Human : int :: ○○ {○○にあなたの家族の人数を入れてください}
  4.  
  5. do Dbg@Log("あなたは、りんご(" ~ Apple.ToStr() ~ "g)を" ~ Human.ToStr() ~ "人で分けました。")
  6. do Dbg@Log("あなたは、そのうちの1切れ(" ~ (Apple / (Human$float)).ToStr() ~ "g)を食べました")
  7. end func
しかし、5人家族ぐらいまでならこれで良いのですが、さすがに10人家族でりんご1つを分けるのはひもじすぎます。
そこで6人以上の家族には、見かねたくいなちゃんが回らない寿司をおごってくれるとしましょう。流石くいなちゃん!人のお金で食べるオスシィは美味い!!!
さて、今話したことを日本語で記述すると以下のようになります(※まだ日本語なので予期したとおりには動きません)
  1. func Main()
  2. var Apple : float :: 250.0
  3. var Human : int :: ○○ {○○にあなたの家族の人数を入れてください}
  4.  
  5. {もし、Humanの数が5以下だったら}
  6. do Dbg@Log("あなたは、りんご(" ~ Apple.ToStr() ~ "g)を" ~ Human.ToStr() ~ "人で分けました。")
  7. do Dbg@Log("あなたは、そのうちの1切れ(" ~ (Apple / (Human$float)).ToStr() ~ "g)を食べました")
  8. {それ以外だったら}
  9. do Dbg@Log("あなたは、りんご(" ~ Apple.ToStr() ~ "g)を" ~ Human.ToStr() ~ "人で分けようとしました。")
  10. do Dbg@Log("見かねたくいなちゃんがあなた達にお寿司をおごってくれました。りんごはスタッフがおいしくいただきました。")
  11. end func
6人以上の家族にはくいなちゃんがお寿司をおごってくれるようになりました。そして重要なのは 寿司を食べたのでりんごは食べてません。
つまり、人数に応じて「りんごor寿司」を選択するようになったのです。 二者択一です。
このように、ある特定の条件(今回は「人数が5人以下かそうでないか」)を満たすかどうかで、実行する命令(今回はDbg@Logで表示する内容である「りんごと寿司のどっちを食べたかの出力」)を変える事ができる構文を 条件分岐文 と言います。
因みに、先ほどの例を、条件分岐文の一つであるif文で記述すると、以下のようになります。
  1. func Main()
  2. var Apple : float :: 250.0
  3. var Human : int :: ○○ {○○にあなたの家族の人数を入れてください}
  4.  
  5. if(Human <= 5)
  6. do Dbg@Log("あなたは、りんご(" ~ Apple.ToStr() ~ "g)を" ~ Human.ToStr() ~ "人で分けました。")
  7. do Dbg@Log("あなたは、そのうちの1切れ(" ~ (Apple / (Human$float)).ToStr() ~ "g)を食べました")
  8. else
  9. do Dbg@Log("あなたは、りんご(" ~ Apple.ToStr() ~ "g)を" ~ Human.ToStr() ~ "人で分けようとしました。")
  10. do Dbg@Log("見かねたくいなちゃんがあなた達にお寿司をおごってくれました。りんごはスタッフがおいしくいただきました。")
  11. end if
  12. end func
どうでしょうか、日本語で記述した時に似ている形になったのではないでしょうか。
ifとは、日本語で「もし~ならば」と訳し、if以降の()の中で、(Human <= 5)と書いてあるので、「もし、Humanが5以下ならば」と脳内で思ってくれれば結構です。
elseは「そうでなければ」と脳内で訳してください。つまり、「もし、Humanが5以下でなければ」と解釈します。
終了時にはend ifで「if文を終了します」という意味になります。
・・・お分かりいただけただろうか? ざっくりお分かりいただけたならば、以下では、上記に使用したif文を含め、3種類の条件分岐について説明していこうと思います~

if文

説明

一番オーソドックスな条件分岐文です。if文さえマスターしてしまえば、(理論上)どんな条件分岐にも対応することが出来るようになります。[要出典]
プログラミングを始めたばかりの人は、まずはif文をマスターしましょう。
しばらく使っていると、if文の不便なところにも気づくと思います。不便だな、感じる場所に遭遇したらswitch文や条件演算を利用するようにすると、より良いコーディングになるかと思います。

記述方法

  1. func Main()
  2. if( {条件式1(bool型)} ) {ifは、「もし 条件式1 ならば~」と思ってください}
  3. {条件式1のboolの値がtrueの時に実行される行}
  4. {...(ここにプログラムを入れてください)}
  5. {条件式1のboolの値がtrueの時に実行される行ここまで}
  6. elif( {条件式2(bool型)} ) {elifは、「そうでなくてもし 条件式2 ならば~」と思ってください}
  7. {条件式1のboolの値がfalseで、かつ条件式2のboolの値がtrueの時に実行される行}
  8. {...(ここにプログラムを入れてください)}
  9. {条件式1のboolの値がfalseで、かつ条件式2のboolの値がtrueの時に実行される行ここまで}
  10. else {elseは、「今までの条件を満たさなければ~」と思ってください}
  11. {条件式1のboolの値がfalseで、かつ条件式2のboolの値がfalseの時に実行される行}
  12. {...(ここにプログラムを入れてください)}
  13. {条件式1のboolの値がfalseで、かつ条件式2のboolの値がfalseの時に実行される行ここまで}
  14. end if
  15. end func

特徴・備考

  • elif及びelse節は省略することも可能
  • ものすごく汎用性が高い
  • 汎用性の高さ故に、使い過ぎるとプログラムが追いにくくなることも

向き不向き

  • 一般的な条件分岐用途には問題なく使えます
  • 似たような分岐で、elifが大量に出来てしまう場合には面倒になることも。その時は後述のswitchを検討してみましょう



switch文

説明

ある特定の変数を、その変数に入ってる値によって分岐させる時に、if文を超えた輝きをみせるようになる条件分岐文です。
しばしばenumと組み合わせて、ステート管理をするときに使われたりします。

記述方法

  1. func Main()
  2. switch(変数)
  3. case (変数の値1)
  4. {変数の値が1の時のステート}
  5. case (変数の値2)
  6. {変数の値が2の時のステート}
  7. case (変数の値3)
  8. {変数の値が3の時のステート}
  9. case (変数の値4,変数の値5)
  10. {変数の値が4もしくは5の時のステート}
  11. case (変数の値6 to 変数の値7)
  12. {変数の値が67の時のステート}
  13. default
  14. {変数の値が上記のいずれにも該当しなかった時のステート}
  15. end switch
  16. end func

サンプルコード(Ver1.00)

  1. func Main()
  2. var state : int :: -1
  3. var coin : int :: 0
  4.  
  5. while mainLoop(true)
  6. switch(state)
  7. case (-1)
  8. do Dbg@Log("喉が乾きました。自動販売機で120円の飲み物を買おうと思います。")
  9. do Dbg@Log("あなたは50円玉、100円玉をたくさん持ってます。10円は何故か持ってません。")
  10. do Dbg@Log("50円を入れるならキーボードのZを押し、100円を入れるならキーボードのXを押してください。")
  11. do Dbg@Log("もう要らないよっって時には、キーボードのCを押してください。")
  12. do state :: 0
  13. case (0)
  14. {
  15. 現在の投入金額を表示するステートです。
  16. このあとに、投入金額が120円を超えるか超えないかで、次のステートを決定させます。
  17. }
  18. do Dbg@Log("自動販売機には"~ coin.ToStr() ~"円入っています")
  19.  
  20. if(coin<120)
  21. do state :: 1
  22. else
  23. do state :: 2
  24. end if
  25. case (1)
  26. {
  27. 投入合計金額が120円に満たない時のステートです。
  28. この時は何もせず待機します
  29. }
  30. case (2)
  31. {
  32. 投入金額が120円を超えた時のステートです。
  33. この時はジュースを出して、投入合計金額をジュース代の120円分引きます
  34. さらに、現在の金額を表示させるステートに戻してあげます。
  35. }
  36. do Dbg@Log("120円ジュースが出てきた!おいしい!")
  37. do coin :- 120
  38. do state :: 0
  39. case (3)
  40. {
  41. キャンセルボタンが押された時のステートです。
  42. この時は、お釣りを返してあげて、プログラムを終了させます。
  43. }
  44. do Dbg@Log("キャンセルします")
  45. do Dbg@Log("お釣りが" ~ coin.ToStr() ~ "円帰ってきました")
  46. break mainLoop
  47. default
  48. {
  49. それ以外の数値になってしまったときのステートです。
  50. 今回はありえないステートなのですが、バグでここに行き着くことがあるので、例外処理をしましょう
  51. }
  52. do Dbg@Log("予期しないステート(" ~ state.ToStr() ~")にたどり着いてしまいました")
  53. break mainLoop
  54. end switch
  55.  
  56. if(Input@Pad(0, Input@EBtn#A) = 1) {Aボタンが押されたら(キーボードでいうZキー)}
  57. {50円を足してから、合計金額確認ステートに飛ぶようにする}
  58. do coin :+ 50
  59. do state :: 0
  60. end if
  61. if(Input@Pad(0, Input@EBtn#B) = 1) {Bボタンが押されたら(キーボードでいうXキー)}
  62. {100円を足してから、合計金額確認ステートに飛ぶようにする}
  63. do coin :+ 100
  64. do state :: 0
  65. end if
  66. if(Input@Pad(0, Input@EBtn#C) = 1) {Cボタンが押されたら(キーボードでいうCキー)}
  67. {キャンセルステートに飛ぶようにする}
  68. do state :: 3
  69. end if
  70.  
  71. do Kuin@Act()
  72. end while
  73.  
  74. do Dbg@Log("プログラムを終了します")
  75. end func

特徴・備考

  • C言語など、他の言語を学習している人向けの話だが、breakは不要です。
  • defaultは省略可能(時と場合によっては、例外処理を挟んだほうが望ましいこともある)
  • case (min to max)の形で、maxの値を省略することが出来ないので、変数が〇〇より大きい、という比較にも弱い
  • かなり角張った記述になるので、数百行、数千行に渡るソースコードになった時に、switchステートは目立ちやすい

向き不向き

  • ステートマシンの作成向き。enumとの親和性は非常に良好
  • 変数の値の分岐に特化している分、複数の変数の比較などにはめっぽう弱い



条件演算