この記事は、C言語ドリルの3本目として for / while(ループ)を練習する記事です。10回繰り返し処理の実装方法について身に着けます。

for / while / do-whileを7問の練習問題(基礎5問+発展2問)で手を動かして固めるドリルです。解答と解説は各問題の「+」を押すと開きます。まず自分で書いてみて、それから答え合わせをしてください。マイコンのプログラムは「電源が入っている間ずっと繰り返す」のが基本形なので、ループは組込みの心臓部になります。

<自己紹介>
筆者は現役の組込みエンジニアです。未経験向けのC言語練習問題を通じて最低限の言語知識を身につけ、最終的にはArduinoでマイコンプログラムを自作できるようになるのをゴールとして、このシリーズを作成しています。

このテーマの要点

ループでやることはこれだけ

  • 回数が決まっている繰り返しは for
  • 条件が続く間ずっとの繰り返しは while(最低1回は実行したいなら do-while
  • break で途中終了、continue でその回だけ飛ばす

ループを覚えると、「100個のデータを順に処理する」「終了の合図が来るまで動き続ける」といった、人間には面倒な仕事をプログラムに任せられるようになります。次の配列とはセットで使う相棒どうしです。

前提知識:for・while・do-while

C言語の繰り返しは3種類です。違いは「条件をいつ判定するか」と「回数が決まっているか」だけです。

書き方 いつ使う 特徴
for 回数が決まっている繰り返し 初期化・条件・更新を1行にまとめて書く
while 条件を満たす間ずっと 開始前に条件が偽なら、1回も実行されない
do-while 最低1回は実行したいとき 先に実行してから条件を判定する

① for(回数が決まっている繰り返し)

for

for (int i = 0; i < 5; i++) {
    printf("%d\n", i);   // 0,1,2,3,4 と5回
}

for は「①初期化 i = 0 → ②条件 i < 5 → ③更新 i++」の3点セットです。条件が真の間だけ { } を繰り返します。

ターミナルに「1 回目のループ」から「5 回目のループ」まで5行表示された実行結果
筆者の環境でforループを実行した例。同じ printf が5回繰り返され、i の値だけが進んでいく

② while(条件が続く間ずっと)

while

int i = 0;
while (i < 5) {
    printf("%d\n", i);
    i++;                 // これを忘れると無限ループ!
}

回数が決まっていない繰り返し(「終了の合図が来るまで」など)は while が向きます。条件を進める1行(i++)を自分で書くのを忘れないでください。

③ do-while(最低1回は実行する)

do-while

int i = 10;
do {
    printf("%d\n", i);   // 条件が偽でも、まず1回実行される
    i++;
} while (i < 5);

while との違いは判定のタイミングだけです。while は「判定してから実行」、do-while は「実行してから判定」。だから上の例は、i = 10 で条件が最初から偽でも、1回だけ表示されます。「まず1回動かして、結果を見て続けるか決める」場面で使います。

④ インクリメント・デクリメント演算子(前置と後置)

ループとセットでよく使う i++ は「iを1増やす」演算子です。1減らすのは i--。実は書く位置で動きが少し変わります。

書き方 名前 a=1, b=1b = ◯◯(書き方); をした結果
++a 前置インクリメント a=2、b=2(先に増やしてから渡す)
a++ 後置インクリメント a=2、b=1(渡してから増やす
--a 前置デクリメント a=0、b=0
a-- 後置デクリメント a=0、b=1

「前置は先に増減、後置は後で増減」です。ただし for の更新部分では、前置でも後置でもループの動きは変わりません。単独で使う分には好みや開発現場のコーディングルールに従えば大丈夫です。差が出るのは代入と組み合わせたときだけなので、Q5で確かめます。
※私の体感としては殆どのプロジェクトでは後置を使用しているのでそちらに統一しておけばよいかと思います。

より正確な仕様は、cppreference(C言語リファレンス)で確認できます。

例題(for と while、それぞれ一緒に解く)

練習問題に入る前に、for と while で同じこと(1〜3の表示)を、答えを見ながら確認しましょう。書き方は違っても結果は同じです。

例題① for:1から3までを表示する。

for.c

#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 3; i++) {
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}

実行結果:1 2 3 … for は「初期化 i=1・条件 i<=3・更新 i++」を1行にまとめて書きます。

例題② while:同じく1から3までを表示する。

while.c

#include <stdio.h>

int main(void) {
    int i = 1;
    while (i <= 3) {
        printf("%d ", i);
        i++;
    }
    printf("\n");
    return 0;
}

実行結果:1 2 3 … while は「初期化」と「更新 i++」を自分でバラバラに書きます。i++ を忘れると無限ループになるので注意です。

解説:回数がはっきり決まっているなら for、条件が続く間だけ回すなら while が向いています。まずは同じ結果になることを確かめられれば十分です。ここからは自分の手で解いてみましょう。

練習問題(基礎5+発展2)

基礎5問は必ず解いてください。発展2問は余力があればで大丈夫です。まず自分で書いてから、各問題の「+ 解答・解説を見る」を開いて答え合わせをしましょう。

基礎 Q1

for を使って、1から5までの数字を空白区切りで表示してください。

解答・解説を見る
q1.c

#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 5; i++) {
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}

実行結果:1 2 3 4 5

解説:i = 1 から始めて、i <= 5(5以下)の間くり返し、毎回 i++ で1増やします。<=(以下)なので5まで含みます。ここを <(未満)にすると4で止まるので、回数のズレに注意してください。

基礎 Q2

次のfor文がちょうど5回繰り返されるように、x に入れる値を考えてください。

問題のコード

for (int i = 0; i < x; i++) {
    printf("実行回数:%d\n", i + 1);
}
解答・解説を見る
q2.c

#include <stdio.h>

int main(void) {
    int x = 5;   // 答え:5
    for (int i = 0; i < x; i++) {
        printf("実行回数:%d\n", i + 1);
    }
    return 0;
}

実行結果:実行回数:1実行回数:5

解説:答えは x = 5 です。i = 0 から始まり、i < 5(未満)なので i は 0,1,2,3,4 の5回。「0始まりで < なら、条件の数がそのまま回数」と覚えると数えやすいです。表示は i + 1 にしているので1〜5になります。この「開始値と条件の組み合わせで回数を読む」感覚は、他人のコードを読むときに必ず使います。

基礎 Q3

while を使って、1から10までの合計を計算して表示してください。

解答・解説を見る
q3.c

#include <stdio.h>

int main(void) {
    int sum = 0;
    int i = 1;
    while (i <= 10) {
        sum += i;   // sum = sum + i
        i++;
    }
    printf("%d\n", sum);
    return 0;
}

実行結果:55

解説:sum += i は「今の合計に i を足す」という書き方(sum = sum + i と同じ)です。i++ を書き忘れると i がずっと1のままで、永遠に終わらない無限ループになります。while では「条件を進める1行」を必ず入れてください。

基礎 Q4

1から10まで数えながら、3の倍数は飛ばし(continue)、8になったら終了(breakして、表示された数字を確かめてください。

解答・解説を見る
q4.c

#include <stdio.h>

int main(void) {
    for (int i = 1; i <= 10; i++) {
        if (i == 8) break;         // 8で終了
        if (i % 3 == 0) continue;  // 3の倍数は飛ばす
        printf("%d ", i);
    }
    printf("\n");
    return 0;
}

実行結果:1 2 4 5 7

解説:continue は「その回の残りをスキップして次の i へ」進みます。だから3と6は表示されません。break は「ループごと抜ける」ので、8になった瞬間に終了し、8以降は出ません。%(余り)は割り切れると0になるので、i % 3 == 0 で「3の倍数か」を判定できます。

基礎 Q5

int a = 1, b = 1; のとき、①b = ++a; をした後の a と b、②(変数を1,1に戻してから)b = a++; をした後の a と b。実行する前に予想してから、プログラムで確かめてください。

解答・解説を見る
q5.c

#include <stdio.h>

int main(void) {
    int a = 1, b = 1;
    b = ++a;                            // 前置:先に増やしてから渡す
    printf("a=%d b=%d\n", a, b);        // a=2 b=2

    a = 1; b = 1;                       // リセット
    b = a++;                            // 後置:渡してから増やす
    printf("a=%d b=%d\n", a, b);        // a=2 b=1
    return 0;
}

実行結果:a=2 b=2a=2 b=1

解説:どちらも最終的に a は2になりますが、bに渡る値が違います。前置 ++a は「増やしてから値を渡す」ので b=2。後置 a++ は「今の値を渡してから増やす」ので b=1。この差は代入と組み合わせたときだけ現れます。for文の更新部分(i++)では差が出ないので安心してください。他人のコードで b = a++ を見かけたら、この問題を思い出しましょう。

発展 Q6

int i = 10; から始めて、while (i < 5)do { } while (i < 5)両方で「hello」を表示するループを書き、実行回数の違いを確かめてください。

解答・解説を見る
q6.c

#include <stdio.h>

int main(void) {
    int i = 10;
    while (i < 5) {
        printf("hello (while)\n");   // 1回も実行されない
        i++;
    }

    i = 10;
    do {
        printf("hello (do-while)\n"); // 1回だけ実行される
        i++;
    } while (i < 5);
    return 0;
}

実行結果:hello (do-while) が1回だけ

解説:i = 10 は最初から条件 i < 5 を満たしていません。while は「判定してから実行」なので0回do-while は「実行してから判定」なので1回だけ動きます。この「最低1回は実行される」性質は、「まず1回計測して、結果次第で繰り返す」ような処理で役立ちます。

発展 Q7

数あてゲームを作ります。正解の数 secret = 7(0〜10)に対して、キーボードから数を入力(scanf)して、当たれば「win」と表示して終了、外れれば「miss」と表示して再入力。3回外したら「lose」と表示してください。if文とループの総合問題です。

解答・解説を見る
q7.c

#include <stdio.h>

int main(void) {
    int secret = 7;   // 本来は乱数で作る(まずは固定でOK)
    int guess = 0;
    int win = 0;

    for (int i = 0; i < 3; i++) {        // 挑戦は3回まで
        printf("0-10の数を入力: ");
        scanf("%d", &guess);
        if (guess == secret) {
            win = 1;
            break;                        // 当たったら即終了
        }
        printf("miss\n");
    }

    if (win == 1) {
        printf("win\n");
    } else {
        printf("lose\n");
    }
    return 0;
}

実行例:5 → miss、7 → win(3回外すと lose)

解説:「3回まで」を for で数え、「当たったら途中で抜ける」を break で実現しています。当たったかどうかは win というフラグ変数(0/1)に覚えさせて、ループを抜けた後に判定します。このフラグの使い方は実務でも頻出です。scanf("%d", &guess) はキーボードから整数を読む関数で、変数名の前の & は「変数の場所(アドレス)を渡す」印。この & の意味はポインタの記事で詳しく説明するので、いまは「scanfでは付けるもの」で大丈夫です。

この発展問題は余力がある人向けです。基礎5問ができていれば、次のテーマ(配列)に進んで大丈夫です。

例:実務で実際に書くコード

マイコンのプログラムには、あえて「終わり」を設けず電源が入っている間、無限に処理をし続けるメインループを設けて処理を書くことが多いです
⇒特定のカウントでいきなりプログラムが止まってしまうなんてことがあった大変なことになっちゃいますからね。

例:組込みプログラムの骨組み(メインループ)

int main(void) {
    init_device();            // 最初に1回だけ初期化

    while (1) {               // 無限ループ:電源が切れるまで回り続ける
        int value = read_sensor();   // ①入力を読む
        int result = judge(value);   // ②判断する
        write_output(result);        // ③出力する
    }
}
  • while (1) は条件がいつも真なので意図的な無限ループです。組込みではよくよくこのように無限ループを作成します。
  • この無限ループの中で「入力→判断→出力」を延々と繰り返すのが、マイコン動作になります。
  • 「10回だけ再試行する」「異常が出たら break で抜けて安全処理へ」のように、forやbreakも組み合わせます

私が車載の現場で扱う制御ソフトも、この無限ループを使用しています。決まった周期(たとえば10ミリ秒ごと)で同じ処理を回し続け、毎回センサーを読み、判断し、出力する。Q1〜Q7で練習した「回数を数える」「条件で抜ける」「フラグで覚える」は、そのままこのループの中身を書く技術になります。

最後につまずきポイントをおさらい

回数が1つズレる(<= と < の違い)
「5回くり返すつもりが4回や6回になっていた」というズレは、for の条件でよく起きます。i = 1; i <= 5 なら5回、i = 0; i < 5 でも5回です。「開始の値」と「<= か < か」の組み合わせで回数が決まるので、迷ったら手で数えて確かめてください。

もう一つは意図しない無限ループです。while で「条件を進める1行(i++ など)」を書き忘れると、条件がずっと真のままで止まらなくなります。プログラムが固まったように見えたら、まずループの中でカウンタが進んでいるかを確認しましょう。while (1) のような意図した無限ループと違い、こちらは「抜けるつもりなのに抜けられない」のが問題です。

よくある質問(FAQ)

for と while、どっちを使えばいい?

回数が決まっているなら for、決まっていないなら while、が基本です。「5回」「配列の要素ぶん」なら for、「条件が成り立つ間ずっと」なら while が読みやすくなります。

do-while はいつ使う?

「まず1回実行してから、続けるか判定したい」ときです。発展Q6のとおり、whileと違って最低1回は必ず動きます。使う頻度は for / while より低いので、「そういう仲間がいる」と覚えておけば十分です。

無限ループはバグじゃないの?

書き忘れによる無限ループはバグですが、while (1)意図して書く無限ループは正当な書き方です。組込みのメインループのように「止まらないことが正しい」プログラムで使います。大事なのは、意図があるかどうかです。

次に読む

繰り返しができるようになったら、次は「複数のデータをまとめて扱う」配列です。ループと配列は相性抜群で、セットで使います。

次のドリル(#4)C言語 配列の練習問題7問|添字・2次元配列まで固める
前のドリル(#2)C言語 if文の練習問題7問|switch・三項演算子まで固める
目次へ戻るC言語 基礎ドリル|組込みに必要な8テーマの練習問題まとめ