【C言語】繰り返し処理(for文,while文,do~while文,多重ループ)について解説!

C言語における繰り返し処理

C原語における繰り返し処理を記述するために、for文、while文、do~while文という三種類の文が用意されています。本記事ではそれらについて解説いたします。

for文

for文の書式

for文は、{}で囲まれた処理を、指定した条件が満たされるまで繰り返す処理です。

繰り返し処理はループ処理と呼ばれることから、for文によるループを、forループとも呼びます。

forループはC言語のプログラミングでめちゃくちゃ使うので、しっかり覚えておきましょう。

for文の書式は以下のようになります。

for( 初期化処理 ; 条件式 ; 増分処理){
   処理
}

これだけでは、よくわからないと思いますので、例を見ながら進めていきましょう。

for文を用いた例文

for文を用いた、1から10までの数字を表示するコードを書いてみました。

#include <stdio.h>

int main() {
    int i;
    // 1から10までの数字を表示するfor文
    for (i = 1; i <= 10; i++) {
        printf("%d\n", i);  // iの値を表示
    }
    
    return 0;
}

実行結果は以下のようになります。

1
2
3
4
5
6
7
8
9
10

先ほどのfor文の書式に当てはめてみましょう。

まず初期化処理ですが、「 i = 1;」としていますから、最初のiの値は1から始まります。

次に、条件式はif分で用いられているものと同じで、この場合「 i <=10 」ですから、iが10以下の場合この処理は継続されます。

そして最後に、増分処理には「 i++ 」と書いてありますが、これは一体何でしょうか。これはインクリメントといい、iの値を1増加させる処理です。

以上よりこのfor文は、「i = 1から1ずつ増分させて、iが10 以下 ( i <= 10 ) ならば{}内の処理を実行することを繰り返し、iが10より大きくなれば ( i > 10 ) 、ループを抜ける」処理といえます。

インクリメント・デクリメント

for文では、このインクリメントまたは、デクリメントという処理をよく行います。

デクリメントとは、インクリメントの反対の意で、変数の値を1減らす処理です。

そして実は、インクリメント・デクリメントにはそれぞれ2種類存在します。それらを表にまとめると以下のようになります。

演算子呼び名意味該当する演算
i++インクリメント(後置)変数の値を1増加させるi = i+1;
i += 1;
++iインクリメント(前置)変数の値を1増加させるi = i+1;
i += 1;
i–デクリメント(後置)変数の値を1減少させるi = i-1;
i -= 1;
–iデクリメント(前置)変数の値を1減少させるi = i-1;
i -= 1;

これを見て、「ん?++i と i++ ,–i と i– って何が違うんだ?」と思った方、大変素晴らしいです。

これら2つずつは、似ていながらも処理が微妙に異なります。例を用いて見ていきましょう。

以下は前置インクリメント・後置インクリメントの違いを表すサンプルコードです。

#include <stdio.h>

int main() {
    int i = 5; // 初期値を 5 に設定

    // 前置インクリメント (++i)
    printf("前置インクリメント: ++i = %d\n", ++i); // iは先に1増えるので、6が表示される
    // ++iを実行した後、iは6になっている
    printf("その後のiの値: i = %d\n", i);

    // 後置インクリメント (i++)
    i = 5; // iを再び5に設定
    printf("後置インクリメント: i++ = %d\n", i++); // iはまず表示され、その後で1増える
    // i++を実行した後、iは6になっている
    printf("その後のiの値: i = %d\n", i); // iは後置インクリメントのため、6になっている

    return 0;
}

ほいで、実行結果がこちら。

前置インクリメント: ++i = 6
その後のiの値: i = 6

後置インクリメント: i++ = 5
その後のiの値: i = 6

コメントに書いてあるので、ほぼ説明不要だと思われますが、念の為追加で解説します。

前置インクリメントでは、最初にiの値が1増加してから、その増加後の値が表示されます。

今回の例だと最初にi = 5で、++iの後で i は6になります。

後置インクリメントでは、まず元のiの値が表示され、次にiの値が1増加します。

今回の例では、最初にi = 5で、元々のiの値である5を出力した後で、iは1増加します。

  • ++i は「最初に増加させてから使う」
  • i++ は「使ってから増加させる」

このように、++i と i++ の違いは「値を使うタイミング」が異なりますが、最終的にはどちらも変数 i の値を1増やすと覚えましょう。

多重ループ

多重ループとは

多重ループとは、繰り返し処理(ループ)構造の中に別の繰り返し構造が含まれているものです。

ループの入れ子(ネスト)構造とも呼ばれます。多重ループはネストの数に応じて、二重ループ、三重ループ、・・・と呼ばれます。

多重ループは、行列の処理や2次元配列の操作など、複雑なデータ処理に活用されます。

一番使用度が高いのは二重ループです。

for文における多重ループ

実際にforの二重ループ、もしくはforのネストとよばれる処理を作ってみましょう。

この処理はループの中に更にforループを記述する二重の処理で、よく用いられます。

以下のサンプルコードは1から10までの数字を二度繰り返して表示します。

#include <stdio.h>

int main() {
    int i,j;
    // 1から10までの数字を表示する
    for (i = 0; i < 2; i++) {  // 外側のループ(2回繰り返し)
        for (j = 1; j <= 10; j++) {  // 内側のループ(1から10までの数字を表示)
            printf("%d ", j);  // jを表示
        }
        printf("\n");  // 1回目と2回目の間に改行を入れる
    }
    return 0;
}

実行結果は以下のようになります。

1 2 3 4 5 6 7 8 9 10 
1 2 3 4 5 6 7 8 9 10 

while文

while文の書式

ループ処理はwhile文を用いることによっても実現可能です。

while文の書式は以下のようになります。

whlie(条件式){
    処理
}

while文は、()内の条件が成り立つ間は、{}内に記述されている処理を繰り返します。

while文を用いた例文

例文を見ていきましょう。以下の例文は1~10までの整数を表示するコードです。

#include <stdio.h>

int main() {
    int i = 1;

    // iが10以下であれば繰り返し処理
    while (i <= 10) {
        printf("%d\n", i);  // iの値を表示
        i++;  // iを1増加
    }

    return 0;
}

実行結果は以下。

1
2
3
4
5
6
7
8
9
10

while文によってiの値が1から始まり、インクリメントしながら、i<=10の間で繰り返し処理が行われていることが分かりますね(i=11の時、条件式が偽になるので、ループを抜ける)。

do~while文

do~while文の書式

次に、ループ処理の3つ目である、do~while文について説明します。

do~while文の書式は以下のようになります。

do {
    // 実行したい処理
} while (条件式);

for文、while文のどちらとも似つかない面をしていますね。

doブロック内の処理は、条件に関係なく少なくとも1回は実行されます。

その後、while(条件)により、条件式が真の場合、繰り返し処理を行います。

そして条件式が偽の場合はループが終了します。

最後のwhile文の部分は、先ほど紹介したwhile文と同じと考えて良いです。

do~while文を用いた例文

do~while文を用いた例文を確認してみましょう。

またまた1から10までの数字を1桁ずつ表示するコードです。

#include <stdio.h>

int main() {
    int i = 1;

    // do while文で繰り返し処理
    do {
        printf("%d\n", i);  // iの値を表示
        i++;  // iを1増加
    } while (i <= 10);

    return 0;
}

実行結果は下のようになります。

1
2
3
4
5
6
7
8
9
10

doブロック内では最初iは1で、printf()でその値が表示されます。

その後while文のループ処理が始まり、インクリメントを繰り返し、i<=10が偽になればループ処理を終えます(i=11の時)。

while 文とdo~while文の違い

「while文とdo〜while文は何が違うの?」と疑問をもたれる方もいることでしょう。

じつはこの2つには大きな違いがあるのです。まずは、以下のサンプルを実行してみてください。

#include <stdio.h>

int main() {
    int i;

    // while 文
    printf("while文の例:\n");
    i = 0;  // iが0の時、条件は満たされない
    while (i > 0) {
        printf("while文: iは正の値です。\n");
        i--;  // 実行されない
    }

    // do-while 文
    printf("\ndo-while文の例:\n");
    i = 0;  // iが0の時、条件が満たされないが、1回は実行される
    do {
        printf("do-while文: iは0です。\n");
        i--;  // 1回は実行される
    } while (i > 0);

    return 0;
}

このコードは、while文とdo~while文の違いを表すものです。

まずは、while文の方から見ていきましょう。変数iが0で初期化されていますが、条件が1>0であるため、最初から条件を満たしていません。このため、while文は一度も実行されません

一方do〜while文は、同じくi=0で初期化されていますが、条件が後で評価されるため、ループ内の処理が1改は実行されます。その後に、条件式i>0が評価され、iが0なのでループは終了します。

よって実行結果は以下のようになります。

while文の例:

do-while文の例:
do-while文: iは0です

continueとbreak

最後に、ループの流れを変えるbreakcontinueの使い方を説明します。

break

まずは、ループ処理を途中から抜けるbreakから説明しましょう。

以下のサンプルコードを実行してみてください。

#include <stdio.h>

int main() {
    int i;
    printf("forループ内でbreakの例:\n");
    for (i = 1; i <= 10; i++) {
        if (i == 5) {
            printf("iが5になったので、ループを終了します。\n");
            break;  // iが5になったらループを強制終了
        }
        printf("i = %d\n", i);
    }

    printf("ループ終了後の処理\n");
    
    return 0;
}

このコードは、 forループ内でiを1から10までカウントしています。

ループ内でi==5になったときにif文の条件を満たし、break文が実行され、ループが強制的に終了します。

実行結果は以下のようになります。

forループ内でbreakの例:
i = 1
i = 2
i = 3
i = 4
iが5になったのでループを終了します
ループ終了後の処理

無限ループ

以下のサンプルを御覧ください。

#include <stdio.h>

int main() {
    int count = 0;

    printf("無限ループの例 (while 1):\n");

    while (1) {  // このループは終了条件が無いため無限ループ
        count++;
        printf("カウンタ: %d\n", count);
    }

    return 0;
}

実はこのコードを実行すると、いつまでもカウントアップ&出力してしまいます。

カウンタ: 1
カウンタ: 2
カウンタ: 3
カウンタ: 4
カウンタ: 5


このように、際限なく繰り返されるループのことを無限ループといいます。

無限ループは、while、forでもdo~whileでもできます。いずれもbreakで抜けることができます

無限ループには故意で行うものと、意図せずにできるものがあります。故意に用いる場合は、必要な箇所にbreakを入れて、ループから出ることができます。

しかし、そうでない場合は、強制的にプログラムを終了させる必要がある場合もあります。

continue

continueはループの冒頭部分に戻る処理です。

次のコードは、continueを使ったサンプルです。

#include <stdio.h>

int main() {
    int i;
    printf("forループ内でcontinueの例:\n");
    // 1から10までの数字をループ
    for (i = 1; i <= 10; i++) {
        if (i % 2 == 0) {
            // 偶数の場合はスキップ
            continue;
        }
        printf("奇数: %d\n", i);
    }

    return 0;
}

このコードでは、forループを使い、i=1から10までインクリメントしています。

if(1%2 ==0)の条件で、偶数の場合はcontinueが実行され、printf文をスキップします。

その結果、10以下の奇数が表示されるようになっています。

forループ内でcontinueの例:
奇数: 1
奇数: 3
奇数: 5
奇数: 7
奇数: 9

以上で、分岐処理、繰り返し処理の解説が完了しました。

本ブログでは順次処理の解説は割愛していますが、順次処理・分岐処理・繰り返し処理は、アルゴリズムの三大要素を記述する方法だと言われています。

しかし、これだけでは複雑な実用プログラムを作るためには不十分です。

次からは、より複雑なプログラムを作るために必要な知識を身に着けていくことにしましょう。

本日は最後までご覧いただき、ありがとうございました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA