[C言語入門]単純作業を繰り返しさせるためにfor文を使う

前回のプログラムでは、if文やswitch文を使って処理を分岐させる方法を学びました。
今回は、繰り返し処理を説明します。
プログラム言語において、繰り返し処理は、ループ処理とも呼ばれています。

コンピュータは大量の処理/データを、繰り返し作業させるのが得意です。
人とは違ってコンピュータは、どんなに大量のデータであっても途中であきらめずに作業してくれますし、途中で集中力が途切れて間違えてしまう事も有りません。

そんな繰り返し処理ですが、C言語に限らず、プログラムでのループ処理には大きく分けて2つのパターンがあります。

1.指定した回数繰り返す
2.指定した条件が満たされるまで繰り返す



プログラムの話に入る前に、上記の2パターンの例を日本語で挙げてみます。
例えば銀行の利子を計算するプログラムを作っているとして…

1.指定した回数繰り返す
    年利3%で10万円貯金したら、10年後にいくらになっているか?
 
2.指定した条件が満たされるまで繰り返す
    年利3%で10万円貯金したら、何年後に20万円になるか?



前者は”10年後”という条件が決まっているので、何らかの処理を10回行わなければならない事が分かります。また、後者については”預金が20万円になるまで”という条件は分かっていますが、それが何年後になるかは不明なので何回繰り返すかが事前に分かりません。


今回は、前者の”指定した回数繰り返す”を行うのが得意なfor文の使い方を学びます。

というわけで、1つ目のサンプルプログラムです。

#include <stdio.h>
 
int main()
{
    int loop;
 
    for ( loop = 0; loop < 10; loop = loop+1 ) {
        printf( "%d回目の処理です\n", loop );
    }
 
    return 0;
}



このプログラムをコンパイル & 実行すると以下の結果になります。

$ gcc -Wall -g -o test01 test01.c
 
$ ./test01
0回目の処理です
1回目の処理です
2回目の処理です
3回目の処理です
4回目の処理です
5回目の処理です
6回目の処理です
7回目の処理です
8回目の処理です
9回目の処理です


これまでの知識だとprintf関数を10回も書かなければならないところだったのが、for文のおかげで1つ書けば済むようになりました。


for文の構文ですが、以下のような形になっています。

for ( 初期処理; 終了条件; カウンタの更新 ) {
    処理
}



動作については、以下のルールで処理が行われます。

Step1
    "初期処理"を実行する
 
Step2
    "終了条件"を判定する
    条件が成立しない場合は、for内の処理を行わずにfor文の実行を終える
    条件が成立する場合は、for内の処理を行わずにfor文を実行する
      ※但し、for文内にbreak文がある場合は、そこでfor文の実行を終える
      ※但し、for文内にcontinue文がある場合は、そこでStep3に移る
Step3
    "カウンタの更新"処理を行い、Step2に戻る


Step2で終了条件を判定しますが、初回で条件に一致しなければループを一回も実行しない場合も有りますし、いつまでも一致し続ける場合は無限ループになります。




初期処理、終了条件、カウンタの更新は書かずに省略することも出来ます。

#include <stdio.h>
 
int main()
{
    int loop;
 
    // 初期処理を省略
    printf( "----パターン1----\n" );
    loop = 0;
    for ( ; loop < 5; loop = loop+1 ) {
        printf( "パターン1  %d回目の処理です\n", loop );
 
    }
 
    // カウンタ更新処理を省略
    printf( "----パターン2----\n" );
    for ( loop = 0; loop < 5; ) {
        printf( "パターン2  %d回目の処理です\n", loop );
        loop = loop+1;   // ここでカウンタを更新してみた。
    }
 
 
    return 0;
}



実行結果はこちらです。

$ ./test01
----パターン1----
パターン1  0回目の処理です
パターン1  1回目の処理です
パターン1  2回目の処理です
パターン1  3回目の処理です
パターン1  4回目の処理です
----パターン2----
パターン2  0回目の処理です
パターン2  1回目の処理です
パターン2  2回目の処理です
パターン2  3回目の処理です
パターン2  4回目の処理です




ループカウンタの更新条件を”loop = loop + 1″と書いていますが、ここは”loop++”と書く事も出来ます。
この”++”はインクリメント演算子と呼ばれており、変数の値を1加算させることを意味します。
変数の加減算は、他にも以下のような簡易記述が可能です。

loop--;         // デクリメント演算子   (loop = loop - 1 と同じ意味)
loop += 1;      // 演算+代入を一度に行う(loop = loop + 1 と同じ)
loop += 2;      // 2つ加算する          (loop = loop + 2 と同じ)
loop -= 1;      // 1つ減算する          (loop = loop - 1 と同じ)
loop *= 2;      // 2倍する              (loop = loop * 2 と同じ)
loop /= 2;      // 2で割る              (loop = loop / 2 と同じ)



ですので、最初のサンプルにあった…

    for ( loop = 0; loop < 10; loop = loop+1 ) {
        printf( "%d回目の処理です\n", loop );
    }



は、以下のように書く事も出来ます(下の記述方法の方が一般的です)

    for ( loop = 0; loop < 10; loop++ ) {
        printf( "%d回目の処理です\n", loop );
    }







また、これまでの例ではカウンタ更新をloop = loop+1と1づつ加算させていましたが、それ以外の更新も可能です。

int main()
{
    int loop;
 
    /* 2づつカウントアップする */
    printf( "-- パターン3 --\n" );
    for ( loop = 0; loop < 10 ; loop += 2 ) {
        printf( "  %d回目の処理です\n", loop );
    }
 
    /* 1づつカウントダウンする */
    printf( "-- パターン4 --\n" );
    for ( loop = 5; loop > 0 ; loop-- ) {
        printf( "  %d回目の処理です\n", loop );
    }
 
    return 0;
}




実行結果

$ ./test01
-- パターン3 --
  0回目の処理です
  2回目の処理です
  4回目の処理です
  6回目の処理です
  8回目の処理です
-- パターン4 --
  5回目の処理です
  4回目の処理です
  3回目の処理です
  2回目の処理です
  1回目の処理です






for文では、終了条件を書き間違えると無限ループになってしまうので注意が必要です。
無限ループというのは、文字通り、ある処理を無限に実行し続けるプログラムで、強制終了を行わない限り永遠に動作し続けます。

例えば、以下のプログラムは終了条件が書かれていないので、いつまでまっても処理が終わらりません。

#include <stdio.h>
 
int main()
{
    int loop;
 
    // 無限ループ
    for ( loop = 1; ; loop++ ) {
        printf( "%d回目の処理です\n", loop ); 
    }
 
    return 0;
}



実行結果は以下の通りです。
プログラムを強制終了させる方法はOSによって異なりますが、通常はウィンドウ右上の”×”ボタンをクリックしたり、Ctrl-c(Ctrlキーを押しながらアルファベットのcを押す)ことで終了します。

1回目の処理です
2回目の処理です
3回目の処理です
...
13666回目の処理です
13667回目の処理です
13668回目の処理です
13669回目の処理です
13670回目の処理です
13671回目の処理です
13672回目の処理です
13673回目の処理です
...
^C                      <= ctrl-cを押して強制終了



先ほどの例では、終了条件を書かないことにより無限ループの構造を作っていました。
この終了条件は、if文と同様に”0以外”のときは真、”0″のときは偽、という判定ルールなので、以下のコードも無限ループになります。

    // 無限ループ(終了条件が0以外 -> 常に真になっている)
    for ( loop = 1; 1; loop++ ) {
        printf( "%d回目の処理です\n", loop ); 
    }





for文では指定された回数だけ処理を行う使用するので、終了条件はfor文の条件部(ここでいう条件部というのはfor( aaa; bbb; ccc )におけるbbb部の事です)に書くのが普通ですが、forの処理内に記述することも可能です。
繰り返しの途中でループを強制的に終わらせるにはbreak文を使用します。

以下の処理は先ほどと同様、for文の()内に終了条件が書かれていないので一見無限ループのように見えますが、for内にbreakがあるのでそこでループを抜けます。

int main()
{
    int loop;
 
    /* 無限ループと見せかけて... */
    for ( loop = 0; ; loop++ ) {
        printf( "%d回目の処理です\n", loop );
        printf( " ループ処理A\n" );
 
        if ( loop > 3 ) {
            /* ループを4回目で中断する */
            break;
        }
        printf( " ループ処理B\n" );
 
    }
 
    return 0;
}



実行結果

0回目の処理です
 ループ処理A
 ループ処理B
1回目の処理です
 ループ処理A
 ループ処理B
2回目の処理です
 ループ処理A
 ループ処理B
3回目の処理です
 ループ処理A
 ループ処理B
4回目の処理です
 ループ処理A


このようにループ内側でbreakを書くことで、途中でループを抜けることが出来ました。



また、continue文を書く事で、ループ処理を途中でキャンセルし、次のループに入らせることも出来ます。

int main()
{
    int loop;
 
    for ( loop = 0; loop < 10 ; loop++ ) {
        printf( "%d回目の処理です\n", loop );
 
        if ( loop % 2 == 0 ) {
            /* 偶数の場合は処理しない (loop%2)は2で割った余りを求める式) */
            continue;
        }
 
        printf( "    %dは奇数ですね!!\n", loop );
    }
 
    return 0;
}



実行結果

0回目の処理です
1回目の処理です
    1は奇数ですね!!
2回目の処理です
3回目の処理です
    3は奇数ですね!!
4回目の処理です
5回目の処理です
    5は奇数ですね!!
6回目の処理です
7回目の処理です
    7は奇数ですね!!
8回目の処理です
9回目の処理です
    9は奇数ですね!!


特定の条件に一致した時に、後続の処理を行いたくない場合に,continueを使用します。

関連記事

コメントを残す

メールアドレスが公開されることはありません。