繰り返し while

Last-modified: 2013-04-18 (木) 16:07:35
 

目標

繰り返しとは何か理解し、while 文で繰り返しが書けるようにする。

プログラムの構造化定理 (再掲)

プログラムは次の3つの構造の組み合わせで、どんなことでも表現できることが数学的に証明されています。

  • 連接 (順次)
  • 分岐 (選択)
  • 繰り返し

連接は、上から下にへ、書かれた順番でプログラムを実行するという意味です。
これは、今までのプログラムで無意識に利用してきました。

今回は、3番目の繰り返しにあたる構造を勉強します。

繰り返しとは

たとえば、1 から 100 までの整数を足すことを考えてみます。
これをそのまま数学の式で書くと、次のようになります。

1 + 2 + 3 + … + 99 + 100

これはシグマを使って置き換えることができます。

sigma.png

繰り返しとは、このようにある作業 (この場合、足し算) を何回も実行することをいいます。
また、繰り返しのことは、ループとも言います。

繰り返しの例

1 から 100 までの整数を足し、合計を表示するプログラムは次のようになります。

int i, sum;

i = 1;
sum = 0;

while(i <= 100){
    sum = sum + i;
    ++i;
}

printf("%d\n", sum);

上の例では、変数 i が 1 から 100 までインクリメントによって変化します。
そして、その変化する i を sum に加算しています。

i <= 100 というのは、この繰り返しが実行され続ける条件です。
この場合、i が 100 以下な間、括弧 {} の中を繰り返しなさい、という意味になります。

条件として指定できるものは、if 文と同じです。
絶対に成立する条件を指定した場合、プログラムが終了しないので注意してください*1

while 文

while 文は次のような形式をしています。

while(条件){
    条件が成立している間実行する文;
}

たとえば、条件に i < 10 と指定した場合、変数 i が 10 未満な間、括弧の中を実行します。
条件がはじめから成り立っていない場合、一回も実行されません。

以下は、1 から 10 まで表示する例です。

int i;
int a;

i = 1;
a = 10;

while(i <= a){
    printf("%d\n", i);
    ++i;
}

++i (もしくは i++) を忘れないように注意してください。
これを忘れると、i が増えないため、永遠に 1 が表示されます。

break 文

while 文の中で break 文を使うと、条件に関係なく強制的にループを抜けます。

int i;

i = 1;

while(i <= 10){
    if(i == 6){
        break;
    }

    printf("%d\n", i);
    ++i;
}

上の例では、1 から 5 まで表示されます。
i が 6 になったとき (i == 6) に、if 文が成立し、表示される前に強制的にループから抜けるからです。

continue 文

ループを強制的に抜けるには break 文を使うことは既に知っていると思います。
今回は、似たような働きをする continue 文について扱います。

break 文は、以下の図のように強制的にループを終了させる働きをしました。

break.png

一方、continue 文は、括弧内の処理の末尾の次にジャンプします。
continue 文では、ループは終了しませんが、continue 文以降の処理が省かれることになります。

continue.png

break, continue 文は、while, for, do-while 文で利用できます。

無限ループ

while 文の条件に、必ず成立する条件を書いておくループを、無限ループといいます。
以下が無限ループの例です (終了しないので、Ctrl-C で終了してください)。

while(1){
    printf("loop\n");
}

C言語では、0 が (不成立)、0 以外が (成立) として扱われるため、
上記のコードでは、条件が常に成立しています。

無限ループは、起動したら絶対に終了しないプログラム (組み込み分野、家電製品など) で多く用いられます。
また、先ほどの break 文と組み合わせ、非組み込み分野でも利用されます。

以下が break 文と組み合わせた例です。

int a;

printf("0 以上の整数を入力してください。\n");

while(1){
    scanf("%d", &a);

    if(a >= 0){
        break;
    }

    printf("入力された値は 0 未満です。正しく入力しなおしてください。\n");
}

上のコードでは、ユーザーが正しく入力するまで、繰り返し入力を求めます。
無限ループを利用せずに同じ事を実現することも可能ですが、
この場合は無限ループを使ったほうが、わかりやすく直感的です。

ちなみに、無限ループを使わない場合は、以下のようにかけます。

int a;

printf("0 以上の整数を入力してください。\n");

scanf("%d", &a);

while(a < 0){
    printf("入力された値は 0 未満です。正しく入力しなおしてください。\n");

    scanf("%d", &a);
}

課題

課題1

1 から 20 の範囲にある奇数をすべて出力しなさい。

課題2

整数を一つ入力させ、1 からその整数まで出力するプログラムを作りなさい。

実行例

1行目はユーザーの入力です。

./a.out
3
1
2
3
./a.out
5
1
2
3
4
5

課題3

指定された個数の整数を足し、答えを出力するプログラムを作成しなさい。

次のように標準入力から数値を与えます。

3
4 5 1

1行目は、整数の個数です。
2行目は、実際に足す整数です。
この場合、4 + 5 + 1 = 10 なので、10 が答えになります。

実行例

./a.out
1
5
5
./a.out
2
7 4
11
./a.out
3
2 4 3
9

課題4

1 から入力された整数 n まで表示するプログラムを作成しなさい。
その際、指定された整数 a の倍数を表示してはいけない。

ただし、プログラムには continue 文を用いること

入力形式

整数 n, a をスペース区切りで入力します。

n a

実行例

./a.out
6 2
1
3
5
./a.out
10 3
1
2
4
5
7
8
10
./a.out
100 1

挑戦課題

 


*1 意図的な無限ループを除く。