Unity学習記録 #005 繰り返し（for文）

# 繰り返しに使用される制御構文
繰り返しに使用される構文は4つです。
・for文（繰り返す回数が事前に分かっているとき）
・foreach文（配列やリストの要素を順番に処理していくとき）
・while文（繰り返す回数が分からないので、条件がtrueの間は繰り返す）
・do while（条件の判定がループ処理の最後なので、falseでもその回の処理は実行される）

4つもあって覚えるのが大変だと思いますが、それぞれに他の繰り返し構文と異なる特徴がありましたので、そのあたりを説明できればと思います。

また、繰り返し処理の中で、よく使われる予約語が２つあります。
・continue（特定の条件を満たした時のループ処理をスキップ）
・break（特定の条件を満たした時にループ処理を終了）

この２つの予約語に関してもサンプルコードを書いてみます。
<br>

## for文
今回はfor文を見ていきます。まずはfor文の書き方から。
```csharp
for(初期化式; 条件式; 更新式)
{
    //条件がtrueだった時の処理
}
```
実行できるコードを書いてみます。
```csharp
//カウントアップ処理
for(int i = 0; i < 10; i++)
{
    Debug.Log(i + "回目のループ処理");
}
```
実行すると変数 "i" が０から始まり、ループの度に変数 "i" に1が足されて10回の繰り返し処理が実行されます。
forの後に記述する小括弧の中身を見ていくと、１つ目の初期化式では変数 "i" に整数型の0を代入して初期化を行っています。
2つ目の条件式では変数 "i" が10より小さい値であれば中括弧内の処理を実行するという記述です。
3つ目の更新式では変数 "i" に1を足してループ処理を更新するという記述です。
<br>
<strong>for文ではまず条件を判定して、trueであれば中括弧内の処理を実行し、処理の最後に変数を更新するという処理が1ループ毎に実行されています。</strong>
<br>

別のサンプルコードも見てみます。
```csharp
//カウントダウン処理
for (int i = 10; i > 0; i -= 2)
{
    Debug.Log("現在の値:" + i);
}
```
for文ではカウントアップだけでなく、カウントダウンの繰り返し処理もできます。この処理では初期値 "10" から始まる変数 "i" が0より大きい値であれば、結果をコンソールに書き出します。増減値がマイナス2なので、変数 "i" は10, 8, 6… と変化しながらループ処理が実行されます。
<br>

値に定数ではなく、変数を使ったサンプルコードも見てみます。
```csharp
//値を変数で記述
int start = 0; // 初期値
int end = 10; // 終了値
int step = 1;  // 増減値

for (int i = start; i < end; i += step)
{
  Debug.Log(i + "回目のループ処理");
}
```
このサンプルコードでは初期値や増減値を変数で記述しています。同じfor文処理を複数記述することがある場合は、値に変数を設定しておくことで、後からの値の修正が楽になります。
<br>

次のサンプルコードは、for文の中にfor文を記述する書き方です。２次元配列のデータ処理でよく使われる印象があります。
```csharp
//２次元配列処理
for(int i = 1; i <= 3; i++)
{
    for(int j = 1; j <= 5; j++)
    {
        Debug.Log(i + "クラスの" + j + "番目");
    }
}
```
実行すると1クラスの1番目から5番目までを順に出力し、次に2クラスの1番目から5番目を順に出力。その後も条件がtrueの間は同じように処理を繰り返します。
このようなコードの書き方は「入れ子」や「ネスト」と呼ばれます。
※配列については別の記事でまとめようと思います。
<br>

for文では整数型を取り扱う場合が多いようですが、整数以外の型も扱うことができます。
```csharp
// 整数型のループ処理
for (int i = 0; i < 10; i++) {
  // ...
}

// 浮動小数点型のループ処理
for (float f = 0.0f; f < 10.0f; f += 0.1f) {
  // ...
}

// 文字型のループ処理
for (char str = 'a'; str <= 'z'; str++) {
  // ...
}
```
浮動小数や文字列の型も扱えるようでしたので紹介しました。
<br>

ループ処理で実行する処理コードが1行の場合は中括弧を省略した書き方も可能です。
```csharp
//中括弧を省略したfor文の書き方
for (int i = 0; i < 10; i++) Debug.Log(i + "回目のループ処理");
```

## continue（ループ処理のスキップ）
サンプルコードを見てみましょう。
```csharp
for(int i = 0; i < 10; i++)
{
    if (i == 5)
    {
        continue;
    }
    Debug.Log(i);
}
```
変数 "i" は０からカウントアップされてループ処理が実行されていきますが、変数 "i" の値が5のときは、以降の処理をスキップして次のステップのループ処理に移ります。注意すべきことは、continueが読み込まれるまでは処理は実行されるため、スキップする回であっても、continueより上に記述した処理内容はそのループの回で実行されます。
特定の条件でスキップしたい処理は、continueより下の行に記述することになります。

## break（ループ処理を途中で終了）
サンプルコードを見てみましょう。
```csharp
for(int i = 0; i < 10; i++)
{
    if (i == 5)
    {
        break;
    }
    Debug.Log(i);
}
```
continueで説明した内容とほぼ同じですが、breakが読み込まれるとループ処理が途中であっても処理から抜け出します。必要な情報を順に探していき、見つかったらループから抜けて次の処理に移る時などに便利です。
<br>
for文についていくつかのサンプルコードでまとめてみました。
他の繰り返し文も別の記事でまとめようと思います。
<br>

## おまけ情報
### 文字列補完
文字列と変数を複数組み合わせて文字列として出力するときに「+」の演算子を何回も使うのが面倒。
```csharp
for(int i = 1; i <= 3; i++)
{
    for(int j = 1; j <= 5; j++)
    {
        Debug.Log(i + "クラスの" + j + "番目");
    }
}
```
こんな時は文字列の中に変数を埋め込むコードの書き方が便利です。

```csharp
for(int i = 1; i <= 3; i++)
{
    for(int j = 1; j <= 5; j++)
    {
        Debug.Log($"{i}クラスの{j}番目");
    }
}
```
$：文字列の中に変数を埋め込むための宣言のようなもの
{ }：この中に記述した文字列は変数名となり、変数として扱われる

このように、文字列の中に変数（数式も可）を埋め込む機能を "文字列補完" というそうです。

### スコープ
スコープは内容が複雑そうなので紹介程度にします。
スコープは変数、関数、クラスなどの識別子が有効な範囲を定義します。
変数 "i" の型が宣言される場所に注目です。
```csharp
void Function()
{
    for (int i = 0; i < 10; i++)
    {
        Debug.Log(i);  //変数 "i" の型が宣言されている扱い
    }
    Debug.Log(i);  //変数 "i" の型が宣言されていない扱いなのでエラーが出る
}
```
上記のコードのようにfor文の中で型を宣言した変数 "i" は、for文の中では有効ですが、それより外では型の宣言がされていない扱いになります。

次に、for文の外で型を宣言した場合
```csharp
void Function()
{
    int i;
    for (i = 0; i < 10; i++)
    {
        Debug.Log(i); //変数 "i" の型が宣言されている扱い
    }
    Debug.Log(i); //変数 "i" の型が宣言されている扱い
}
```
この場合の変数 "i" は、Function関数の中であれば、どこで呼び出しても型が宣言されている扱いになります。
for文よって変数 "i" の値はループの度に更新されていきますが、for文が終了するときに最後に更新された値がそのまま繰り返し処理以降の行でも適用されます。