14章 WHILE文

http://www.geocities.jp/ky_webid/c/014.html

反復処理の構文ですね。

ある条件が真のとき、ループを続けます。

条件が偽になるか、break文等でループから抜けることができます。

問題1

キーボードから2つの整数を入力させます。次にそれらの数字を足し合わせた数を入力させ、それが正しい足し算の結果になっているかを判定するプログラムを作って下さい。間違っている場合は、最初の2つの整数入力からやり直すようにループさせて下さい。正しい結果を入力できたらプログラムを終了させます。

whileを使い、間違えてる間はループして同じ処理を繰り返すってことですね。

int main () {
    int num1, num2, total;
    
    while(1){
        printf("一つ目\n");
        scanf("%d",&num1);
        printf("一つ目\n");
        scanf("%d",&num2);
        printf("合計\n");
        scanf("%d",&total);
        
        if ( num1 + num2 == total ) {
            printf("正解です\n");
            break;
        }
        else {
            printf("不正解です\n");
        }
    }
    return 0;
}
$ main
一つ目
10
一つ目
20
合計
500
不正解です
一つ目
10
一つ目
20
合計
30
正解です

できました。

答え合わせ

解答例では

while( num1 + num2 != ans ) {
    //
}

とwhileの条件式でチェックしていました。

また補足説明には

書き方はいくらでもあります。ついでにbreak文を使うパターンも考えてみるといいでしょう。その場合、無限ループにして、終了条件判定はif文で行うようになります。こちらの場合、間違った入力のときに「間違っています」のようなメッセージを表示する処理が加えられるので、むしろその方がいいかも知れません。

とあるのでbreak文でよかったと思います。

問題2

次のプログラムはどんなときに終了するでしょう。あるいは終了しないでしょうか。

int main(void){
    char input;

    while( 1 )    {
        printf( "aを入力して下さい\n" );
        scanf( "%c", &input );
        
        switch( input )  /* 入力された文字による分岐 */
        {
        case 'a':   /* aが入力されたとき */
        case 'A':   /* Aが入力されたとき */
            /* 'a'でも'A'でも同じ処理を行う */
            break;
        default:    /* 入力された文字がaでもAでもないとき */
            printf( "%cが入力されました\n", c );
            break;
        }
    }
    return 0;
}

読み解いていきましょう。

「a」か「A」が入力された場合と、それ以外の文字が入力された場合とで処理が分かれています。

それぞれbreakが入ってますが、これはswitch文を抜けるbreakだと思うのでwhileは無限ループするのかな?

もしかしてdefault句の場合はbreak意味ないとか?どうなんでしょう。

答え合わせ

ズバリ無限ループでした。

問題3

キーボードから入力された回数だけ、画面に * を表示するプログラムを作って下さい。

whileで一定の回数処理をすればいいのかなと思います。

int main () {
    int num = 0;

    scanf("%d",&num);
    while(1){
        printf("*");
        num = num - 1;
        if ( num <= 0 ) {
            break;
        }
    }
    return 0;
}

初めはこう書きました。

しかしこれだと0と入力された場合にも*をひとつ表示してしまいます。

修正版がこちら

int main () {
    int num = 0;

    scanf("%d",&num);
    while(1){
        num = num - 1;
        if ( num < 0 ) {
            break;
        }
        printf("*");
    }
    return 0;
}

printfを最後にもって行き、さらにbreakの条件を0より小さくなったらに変更しました。

これでうまく行きました。

また、breakを使わずにwhileの条件式でやる方法も実装してみました。

int main () {
    int num = 0;

    scanf("%d",&num);
    while(num > 0){
        num = num - 1;
        printf("*");
    }
    return 0;
}

こっちの書き方の方がなんだかスッキリしましたね。

こういう場合はwhileの条件式でやった方がいいのかもしれません。

答え合わせ
int main(void){
    int input;        /* 何個の * を表示するかを受け取る変数 */
    int count = 0;    /* これまでに何個の * を表示したかを記憶する変数 */

    printf( "何個 * を表示したいか入力して下さい\n" );
    scanf( "%d", &input );

    while( count < input )  /* 指定された個数だけ表示するまでループ */
    {
        printf( "*" );
        count = count + 1;  /* 表示した個数を加算 */
    }
    return 0;
}

なるほど。

僕の場合は入力された値をそのまま減算して処理しましたが、こちらの方法はcountという変数を用意してそれを加算していくことで入力された値と比較して処理してますね。

なんとなくこっちの書き方の方が良さそうな気がするので次からは注意しますか。