初心者殺しのfor文のネストを解説します

みなさんは`for`文と仲良くやっていますか？私は昨日まで喧嘩ばかりしていました。あっちに行ったりこっちに行ったりと縦横無尽に駆け回る`for`文がなにを考えているのかわかりませんでした。しかし、ふと目に止まったJAVAの質問の解を自分の手でやってみようと試行錯誤していたときに一筋の光が差し込み`for`文がこう言いました。

「友達になろう」と。

### for文の基本

まずは`for`文の基本をおさらいしましょう。`for`文は<b>初期化、条件、変化、実行内容</b>の4つで構成されています。

#### 基本

```java
for (初期化; 条件; 変化) {
  実行内容
}
```

* 初期化
    * 変数の値を決める場所です。プログラミング初心者は初期化と聞くと0になると考えがちですが間違いです。実際はどんな値で開始するかという意味です。`for`文が開始されると<b>最初に一度だけ実行</b>されます。変数の型を宣言するのを忘れないでください
* 条件
    * この条件が`false`になると終了します。つまり<b>条件が満たされている限り実行内容が繰り返されます</b>
* 変化
    * <b>条件に書いた変数がどう変化するのかを指定</b>します
* 実行内容
    * 計算したり文字を出力したりといった内容を書きます

#### 実演

```java
for (int i = 0; i < 10; i++) {
  System.out.println("Hello!");
}
```

* `int`
    * `int`型を宣言しています
* `i = 0`
    * 変数`i`に`0`を代入します
* `i < 10`
    * `i`が`10`未満なら`true`です。つまり`i`が`9`までのあいだは実行内容を繰り返します
* `i++`
    * `i`が1つ増えます
* `System.out.println("Hello!")`
    * `Hello!`という文字を出力します

#### 動き

実演をもとに見ていきましょう。`for`文が開始されると最初に動くのは初期化です。変数`i`の値は`0`ですね。`for`文は`i`は`0`だと確認してから条件に移ります。条件は`i < 10`です。今の時点では`0 < 10`と同じです。日本語に直すと「0は10より小さい」と言えるので条件は`true`ですね。条件が`true`ということが確認できたので実行内容の部分が動きます。

`System.out.println("Hello!")`が実行されると次は変化に移ります。変化は`i++`です。今の時点では`0++`なので`1`になりました。この`1`は実行の変数に代入するために条件に移ります。今の時点では`1 < 10`です。`true`ですね。というわけでまた実行内容に移ります。

この流れが何度も続くと条件のなかが`10 < 10`になります。これは`true`でしょうか？`false`でしょうか？`false`ですね。これで`for`文は終了です。お疲れ様でした。

流れをリスト化すると以下になります。

1. `for`文開始
2. 初期化
3. 条件
4. 実行内容
5. 変化
6. 条件（以下略）
7. 条件が`false`なら`for`文終了

### 実は簡単だったfor文のネスト

`for`文の基本をおさえたところで次はネストです。私は`for`文のネストをなんとなくわかったつもりになっていましたが実際に書いてみると上の`for`文と下の`for`がどういう風に絡むのかという点がわかっていませんでした。

では、九九の計算プログラムを紐解きながらネストの動きを見ていきましょう。

#### 九九を表示するプログラム

```java
public class MultiplicationTable {
	public void multiply() {
		for (int x = 1; x < 10; x++) {
			for (int y = 1; y < 10; y++) {
				System.out.print(x * y);
				System.out.print(" ");
			}
				System.out.println();
		}
	}
}
```

ここから先は「上の`for`文」ではなく「外側の`for`文」、「下の`for`文」ではなく「内側の`for`文」という表現になります。では、3行目からです。`int x = 1;`から実行されます。次に`x < 10;`です。今回は`true`なので実行内容に移ります。初心者は実行内容がどこなのか真っ白になるところですが下の図をご覧ください。

![for文ネスト.png](https://qiita-image-store.s3.amazonaws.com/0/184298/e3ef27e4-1d2f-f793-8afd-1baab023aa75.png)

`for`文を拡大して色分けしました。これを見るとわかるように外側の`for`文の実行内容というのは内側である青の`for`文なんです。内側の`for`文（青）の初期値の`int y = 1`が実行されて条件に移ります。`y < 10;`なので代入して`1 < 10`です。`true`なので実行内容に移ります。`System.out.print(x * y)`です。`x`は外側の`for`文の変数でしたね。今の時点では`x=1`です。なので、ここは`1 * 1`が実行されて結果は`1`です。画面に`1`が表示されて次の行に移ります。`System.out.print(" ")`は半角の空白が表示されます。

ここまで実行されたら次は変化に移ります。`y++`なので`y`が1つ増えて`2`と変化して次は条件に移ります。`y < 10`なので`2 < 10`となり`true`なので、また実行内容へと移ります。`System.out.print(x * y)`です。`1 * 2`なので結果は`2`となり画面へ表示され次の行の半角の空白も表示されて、また変化に移り以降は繰り返しです。このような動きで`y`の値が`9`までいくと画面には`1 2 3 4 5 6 7 8 9 `と表示されますね。このあとなにが起きるかを見てみましょう。

`y++`で`y`が`10`となり条件に移ります。`10 < 10`は`false`なので内側の`for`文（青）の一番下の`System.out.println()`が実行されて改行されます。これで内側の`for`文（青）は終了するので外側の`for`文（赤）に戻ります。ここからは繰り返しです。`2 * 1`から始まり`2 * 9`までいけば改行で`3 * 1`が実行されます。では実際の実行結果を見てみましょう。

```
1 2 3 4 5 6 7 8 9 
2 4 6 8 10 12 14 16 18 
3 6 9 12 15 18 21 24 27 
4 8 12 16 20 24 28 32 36 
5 10 15 20 25 30 35 40 45 
6 12 18 24 30 36 42 48 54 
7 14 21 28 35 42 49 56 63 
8 16 24 32 40 48 56 64 72 
9 18 27 36 45 54 63 72 81 
```

これが`for`文のネストを利用した九九のプログラムの動きです。紐解くと簡単ですね。これを応用して冒頭ではなしたとある質問を作ってみました。その結果がこちらです。

```
■
■■
■■■
■■■■
■■■■■
■■■■■■
■■■■■■■
■■■■■■■■
■■■■■■■■■
■■■■■■■■■■
■■■■■■■■■■
■■■■■■■■■
■■■■■■■■
■■■■■■■
■■■■■■
■■■■■
■■■■
■■■
■■
■
```

これはなにをやっているかというと`for`文を使って`■`の数を1行ごとに増やして三角形を表現したんです。1つずつ増える形と1つずつ減る形を作り上下を合わせたものを表示しました。以下がそのプログラムです。

```java
public class TriangleTop {
	public void traiangle() {
		for (int x = 0; x < 10; x++) {
			for (int y = 0; y < x+1; y++) {
				System.out.print("■");
			}
				System.out.println();
		}
	}
}
```
```java
public class TriangleBottom {
	public void traiangleReverse() {
		for (int x = 0; x < 10; x++) {
			for (int y = 10; y > x; y--) {
				System.out.print("■");
			}
				System.out.println();
		}
	}
}
```

ここまで読んだみなさんなら、もう解説しなくとも紐解けますね。

### あとがき
プログラミング初心者にとって`for`文のネストの動きをすぐに理解するのは難しいです。見るだけではなく、まずは自分の手で試行錯誤するのをおすすめします。今回作った三角形を左側に反転させたものを作りたくなり四角形に挑戦したのですが半角の空白を連続で表示することができずに断念しました。いつか`for`文で簡単な絵を描いてみたいです。

あと、Qiitaはこういう内容の投稿でいいのでしょうか？