Cによるプログラミング入門5
ループ

 コンピュータのいいところは、同じ事を繰り返させても文句を言わないことではないでしょうか。今回は、ループ(反復・繰り返し)について学びます。例によって、サンプルから入りましょう。


 たとえば、int型変数iがあったときに、

for(i = 0; i < 10; i++){
    printf("好きだよ\n");
}

のようなコードを書くと、「printf("好きだよ\n");を10回繰り返せ」という意味になります。数字の10を20に変えれば20回の繰り返しになります。論より証拠で、簡単なプログラムを書いてみましょう。

/* kurikaeshi.c */
#include <stdio.h>

int main(void)
{
    int i;
    for(i = 0; i < 10; i++){
        printf("好きだよ\n");
    }
    return 0;
}

Fig.1 kurikaeshi.exeの実行画面

 このようなものをfor文などと言うのです。

一般に、for文は、特定の変数に対して、(普通は)次のように書くものです。

for(変数の初期化; 処理を続ける条件; 変数の更新){
    処理
}

なお、これを多少変形した書き方もできます。しかし、まず、上の形で覚えるのがよいと思います。

 上の例(kurikaeshi.c)と構文を見比べてみてください。例では、iという変数が使われていますね。そして、「i = 0」が「変数の初期化(はじめに値を与えること)」です。実際、iに0を代入しているわけです。次の、「i < 10」が「処理を続ける条件」です。これは「iが10より小なら」ですね。そして、「i++」が「変数の更新」です。この「i++」は、「iに1足せ」という意味になるのです。(ここで覚えるようにしましょう。ちなみに「i--」だと「iから1引け」という意味になります。)「変数の更新」は、「処理」が1度実行されるごとに、実行されることになっています。
 ゆっくり考えてみましょう。上の例では、まずiに0が代入されます。そして、そのi(中身は0)は当然「i < 10」なので、処理「printf("好きだよ\n");」が実行され、処理が1度行われたので「i++」によりiは1増えて1になります。それからまた、条件「i < 10」がまた調べられ、条件が成り立つ(iが1なので)ので、また、処理「printf("好きだよ\n");」が実行され、次に「i++」でiが1増えて2になります。そして、条件「i < 10」がまたまた調べられ、条件がまだまだ成り立つ(iが2なので)ので処理「printf("好きだよ\n");」が行われ...と処理が続けられていきます。そして、iが10になると、条件「i < 10」が成り立たなくなるので、ここで処理が終わるのです。

 一般に、このような繰り返しをループとも言います。したがって、for文をforループなどとも言うのです。そして、今見た例のiのように「ループを制御するのに使われる変数」をループ変数などともいいます。
 ループ変数は、ループの制御(繰り返すかどうか決めるなど)に使われるものなので、for文の処理そのものでは、使っても使わなくても問題ありません。上の例kurikaeshi.cでは使っていませんね。しかし、使ってもかまわないのです。たとえば、kurikaeshi.cの「printf("好きだよ\n");」を「printf("好きだよ:%d\n", i);」と変更すると、iの中身が「好きだよ:%d\n」の「%d」に入れられたものが出力されます。このプログラムをkurikaeshi2.cとして実行するとFig.2のようになるのです。

/* kurikaeshi2.c */
#include <stdio.h>

int main(void)
{
    int i;
    for(i = 0; i < 10; i++){
        printf("好きだよ:%d\n", i);
    }
    return 0;
}

Fig.2 kurikaeshi2.exeの実行

 Fig.2では、iも一緒に出力しているわけですが、iが0から9まで動いていることにも注意してください。実際、iははじめ0で、「i < 10」の範囲で「処理」が実行されるので、動くのは0から9までなのです。「0から9まで」ということは、処理は10回(9回ではありません)行われたことになりますね。

 「ループ変数の更新」には、他の式も使えます。たとえば、i--を使う例もお見せしておきましょう。

/* kurikaeshi3.c */
#include <stdio.h>

int main(void)
{
    int i;
    for(i = 9; i >= 0; i--){
        printf("好きだよ:%d\n", i);
    }
    return 0;
}

Fig.3 kurikaeshi3.exeの実行

 「i >= 0」は「iが0以上のとき」などと読みます。条件の書き方はif文のときと同じなのです。(前回の最後のあたりを参考にしてください。)上の例は、「はじめにiを9にし、iを1ずつ減らしながら、iが0以上の間」に処理「printf("好きだよ:%d\n", i);」を繰り返すので、Fig.3のような出力になるのです。ちょっと時間をとって考えてみてください。


 ループ(つまり反復構造)にはfor文以外に、while文do-while文などとよばれるものもあります。while文は次のようなものです。

以下のように書くと、「条件」が成り立つ間、「処理」が繰り返されます。

while(条件){
    処理
}

 たとえば、kurikaeshi.cを、while文で書くと、次のようになります。

/* kurikaeshi4.c */
#include <stdio.h>

int main(void)
{
    int i = 0;
    while(i < 10){
        printf("好きだよ\n");
        i++;
    }
    return 0;
}

 while文もfor文と並んでとても重要なので、よく理解しておく必要があります。
 上の例では、まず、ループ変数iを用意すると同時にそれに0を格納しています。これは非常に重要な処理です。というのは、for文には「変数の初期化」という場所があるのですが、while文にはないのです。そのため、while文を実行する前に、ループ変数を適当な値に初期化する必要があるのです。
 実は、Cでは、一般に、初期化しない変数の値は「不定」ということになっています。つまり「int i;」とあれば、これは「iというint型変数を定義した」ということにはなるのですが、iの値が何であるか決められていないのです。(これを「iにはゴミが入っている」などとも言います。)そこで、iをちゃんと初期化しておかないと、わけのわからない数からiがスタートすることになるので、ループがどうなるかわからないのです。
 また、while文の処理の中で、「i++;」としています。(「;」は、これが独立した命令であることを意味します。)これも重要です。このようにしないとiの値は変化せず、したがって0のままになってしまいます。すると、永遠に「i < 10」という条件が成り立ってしまい、「printf("好きだよ\n");」が無限に繰り返されることになるのです。このようなものを無限ループといいます。実は、わざと無限ループを作ることもあるのですが、まちがって作ってしまった無限ループは、とても嫌なバグです。気をつけましょうね。

 do-while文とは次のようなものです。

以下のように書くと、「条件」が成り立つ間、「処理」が繰り返されます。

do{
    処理
}while(条件);

ただし、while文のときと違い、「条件」が「処理」の実行のあとにチェックされるので、「条件」が成り立たなくても、「処理」が1回は実行さることになっています。

 「反復」の実現方法が3つもあると、初心者は嫌な気持ちになるかもしれません。どれを使えばいいんだろうと。どれでも、自然と思えるものを使えばよいのです。


 なお、for文などで、処理が1行しかない場合、中カッコは書かなくてもよいことになっています。つまり、

for(i = 0; i < 10; i++){
    printf("好きだよ\n");
}

for(i = 0; i < 10; i++)
    printf("好きだよ\n");

と書くこともできるのです。ここで、中カッコの「{」と「}」の両方が書いていないことに注意してください。片方だけなくすことはできません。
 また、Cでは改行が自由なので、これを

for(i = 0; i < 10; i++)  printf("好きだよ\n");

などと書くこともできます。while文などでも同じです(実はif文でもそうです)。
 こういう書き方を嫌う人、好む人、いろいろです。みなさんのお好みでよいと思うのですが、「なるべくプログラムが見やすくなるように」という姿勢は持つようにしましょう。

課題5


C入門目次

前のページ  後のページ