While文は悪ではないか？

# While文ってどうなん？


プログラミングにおいてほぼ全ての言語にwhile文はあるのではないだろうか、プログラムを触ったことがある人なら一度は聞いたことや見たことがあるだろう。

ではwhile文とはいったいどういったものか、一応確認しておこう

while(条件){
処理
}

こんな感じである、

ここで注目したいのはwhile文は条件が真の間ループを続けるということである。
つまり偽になるとループから脱出するのである。

とか言われてもうん、そうやん？それがwhile文やん？としか思わないだろう。
ではこレからいくつかのプログラムをみていこう。

まずは簡単なプログラムからみてみよう

```Java:Code1.java
public class Code1{
    public static void main(String[]args){
      int num = 0;

      while(num++ < 5){
        System.out.println(num);
        
      }  
 
    }
}
```

***それfor文でよくね？？？？***

そうです、こういうプログラムはfor文で良いのです。

じゃあ別に活躍する場所があんだろって

じゃあこのプログラムをみてみましょう。

```java:Code2.java
import java.util.Scanner;
public class Code2{
    public static void main(String[]args){
      Scanner sc = new Scanner(System.in);
      int num = sc.nextInt();
      while(num != 0){
        System.out.println("0を押すまでループ");
        num = sc.nextInt();
      }
      System.out.println("終了");
    }
}
```

これは１回目の処理を外に書いているので美しくないですね、do-whileに書き換えてみましょう。

```java:Code3.java
import java.util.Scanner;
public class Code3{
    public static void main(String[]args){
      Scanner sc = new Scanner(System.in);
      int num;
      do{
        System.out.println("0を押すまでループ");
        num = sc.nextInt();
      }while(num != 0);
      System.out.println("終了");
    }
}
```
これでさっきよりマシになりましたね、しかしdo-while文はwhileの後ろに[;]が必要だったりと何かとミスが多くなりがちです。

そして、numが0になったら終了という条件を実現するためにはwhile文は条件が真である間ループするので、〜〜となったら終わりとは相性が悪く、今回の場合だとnum != 0　もしくは　!(num == 0) のように、こうったら終わりたいという条件を否定したものを条件としなければいけません。

***圧倒的ややこしさの極み！！！！！！！！！！***

ならどうすれば良いか。**「無限ループにif文でbreak」**です
では「無限ループにif文でbreak」して書き直してみましょう’。

```java:Code４.java
import java.util.Scanner;
public class Code4{
    public static void main(String[]args){
      Scanner sc = new Scanner(System.in);
      int num;
      while(true){
        System.out.println("0を押すまでループ");
        num = sc.nextInt();

        if(num == 0) break;
      }
      System.out.println("終了");
    }
}
```

さっきより視覚的にループから脱出する条件がわかりやすくなったのではないでしょうか？
今回のdo-whileのようなパターンではなく、単純にループ条件が複雑な場合をみてみましょう。

```Java:Code5.java
import java.util.Scanner;
public class Code5{
    public static void main(String[]args){
      Scanner sc = new Scanner(System.in);
      int a = 0,b = 0,c = 0,count = 0;

      System.out.print("整数を入力してください:");
      a = sc.nextInt();
      System.out.print("整数を入力してください:");
      b = sc.nextInt();
      System.out.print("整数を入力してください:");
      c = sc.nextInt();
      while(a*b>c*c){
        // （a*bがc*cより大きい）が偽になると終了
        System.out.print("整数を入力してください:");
        a = sc.nextInt();
        System.out.print("整数を入力してください:");
        b = sc.nextInt();
        System.out.print("整数を入力してください:");
        System.out.println("==========================");
        c = sc.nextInt();
        count ++;
      }
      System.out.printf("終了まで%d回",count);
    }
}
```
これは3つの整数を入力してaがb未満またはcがa未満またはaが0未満の条件が真の間ループし、ループから脱出した時に何回ループしたかを表示するプログラムです。

```java:Code6.java
import java.util.Scanner;
public class Code6{
    public static void main(String[]args){
      Scanner sc = new Scanner(System.in);
      int a = 0,b = 0,c = 0,count = 0;

      while(true){
        System.out.print("整数を入力してください:");
        a = sc.nextInt();
        System.out.print("整数を入力してください:");
        b = sc.nextInt();
        System.out.print("整数を入力してください:");
        System.out.println("==========================");
        c = sc.nextInt();
        count ++;
        //a*bがc*c以下で終了
        if(a*b <= c*c) break;
      }
      System.out.printf("終了まで%d回",count);
    }
}

```
この二つのプログラムのように条件が複数あり、複雑な条件になる場合、それらが全て成り立っていないときにループから脱出するというものですが
こういった複雑な条件でループするときはCode5の偽になったらループ終了よりCode6の真になったら終了の方が可読性に優れているだろう。

#総括

while文のループ条件が複雑になればなるほど偽になるとループ脱出のwhile文は可読性が下がる。
無限ループにif文でbreakだと真になったら終了にできるため、可読性に優れていると言えるだろう。
さらにif文を置く位置でwhile文の置き換えにもdo-while文の置き換えにもなるのである。
さらにいうと、真ん中に置くと〜〜の動作は一回は保証(do-while的)して、この動作は条件によっては1度も行わないといった少しトリッキーな処理だって簡単に実装できるのである。


#結論

***無限ループにif文でbreakをすこれ！***