【Java】制御構文のまとめ


#構造化プログラミングの要素
 * 順次（順接）
 * 選択
 * 反復

これらを実装する制御構文についてまとめ

#if命令
* boolean変数を==で比較しない 
* NG例 `if (flag == true )` など
* `if (flag)` `if (!flag)` を使う
* 否定を乱用しない
* →肯定文に空文を使い、elseのみ使うなど読みやすくしよう

```java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
    var i = 10;
    if (i == 10) {
      System.out.println("変数iは10です。");
      } else {
      System.out.println("変数iは10ではありません。");
      //以下と同じ
      //System.out.println((i==10)?"変数は10です":"10ではありません");
     }
    }
}
```

###多岐分岐
* 複数の条件に合致しても最初に合致した一個のブロックのみ実行
* **範囲の狭い条件式から記述**する

```java
public static void main(String[] args) {
  var i = 100;
  if (i > 50) {
    System.out.println("変数iは50より大きいです。");
  } else if (i > 30) {
    System.out.println("変数iは30より大きく、50以下です。");
  } else {
    System.out.println("変数iは30以下です。");
  }
}
```

#switch命令
* 等価演算子の多岐分岐を簡単にできる
* case/ default 句で条件分岐
* 式に合致したcase句に処理を移動する
* 該当処理を終えた後switchグロックを抜けるために**明示的にbreakする必要**
* breakしないと**後続のcase/defaultが実行される**
* **フォールスルー**:意図的にbreakせず処理を続けることもできる

``` java
public static void main(String[] args) {
  var rank = "甲";
  switch (rank) {
    case "甲":
      System.out.println("大変良いです。");
      break;
    case "乙":
      System.out.println("良いです。");
      break;
    case "丙":
      System.out.println("がんばりましょう。");
      break;
    default:
      System.out.println("？？？");
      break;
  }
}
```
```java
//フォールスルーで複数のcaseを並べor条件実装
public static void main(String[] args) {
  var drink = "ビール";
  switch (drink) {
    case "日本酒":
    case "ビール":
    case "ワイン":
      System.out.println("醸造酒です。");
      break;
    case "ブランデー":
    case "ウイスキー":
      System.out.println("蒸留酒です。");
      break;
  }
}
```

#while/do 命令
* 条件式がtrueの間doを実行
    * while命令は**前置判定**：先頭で条件式を判定
    * do…while命令は**後置判定**：末尾で判定→条件に依らず一回はループを実行

```java
public class Main {
    public static void main(String[] args) throws Exception {
        var i = 1;
        do {
          System.out.println(i + "番目のループです。");
          i++;
        } while (i < 6);
    }
}
```

#for命令
* 決められた回数のみループする
* カウンター変数(i,j,kなど)は初期化式の中で宣言し初期化する
* カウンター変数に浮動小数点型を使用しない
    * 浮動小数点型では0.1を厳密に表現できないから
* continueで処理をスキップ可能
* **順次演算子**で初期化式/継続条件式/増減式 に複数の条件を列記できる

```java
//NG例：カウンター変数に浮動小数点型
public class Main {
    public static void main(String[] args) throws Exception {
    for (var i = 0.1f; i <= 1.0; i += 0.1f) {
      System.out.println(i);
      //0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.70000005, 0.8000001, 0.9000001
    }
  }
}
```

```java
//順次演算子
public static void main(String[] args) {
    for (var i = 1; i < 6; System.out.println(i + "番目のループです。"), i++);
 }
```

##拡張for命令
* 指定配列やコレクションを先頭から処理
* **仮変数**を介して個々の要素にアクセス
* 仮変数への操作は拡張forループには影響しない

```java
public class Main {
  public static void main(String[] args) {
    var data = new String[] { "neko", "tama", "mike" };
    //拡張for命令
    for (var value : data) {
      System.out.println(value);
    }
  }
}
```

```java
//コマンドライン引数をargsで受け取って拡張forで順に出力する例
public static void main(String[] args) {
  for (var value : args) {
    System.out.println("こんにちは、" + value + "さん!");
  }
}
```

#ループ制御
* **break**：現在のループを強制中断し、そのものを完全に抜ける
* **continue**：**現在の周回のみ**スキップ、ループは継続
* 入れ子ループの場合、内側のみスキップ
* 全体から抜けたい場合、`break ラベル名;`

```java
//指定したループから抜ける
public class Main {
  public static void main(String[] args) {
    limit:
    for (var i = 1; i < 10; i++) {
      for (var j = 1; j < 10; j++) {
        var result = i * j;
        if (result > 50) {
          break limit;
        }
        System.out.printf(" %2d", result);
      }
      System.out.println();
    }
  }
}