C言語基礎|プログラムの流れを繰り返す

はじめに:プログラムにも「日々の繰り返し」がある

現実の作業って、だいたい同じことを何度もやりますよね。
プログラムもまったく同じで、

  • 入力して
  • 計算して
  • 結果を表示して
  • もう一回やるか聞いて

…みたいな流れがとても多いです。

この「同じ処理を何度も実行する」仕組みを 繰り返し(ループ / loop) と呼びます。
C言語では繰り返しのために主に do文 / while文 / for文 の3種類が用意されています。

ここでは、最初に登場する do文(do-while) を、丁寧に解説していきます。

do文って何をする文?

do文(do-while)は、一言でいうとこうです。

  • まずループ本体(繰り返したい処理)を1回実行する。
  • その後で条件(制御式)を評価し、真(非0)ならもう一回実行する。

つまり 必ず1回は実行される のが最大の特徴です。
「最低1回は入力を受け付けたい」「最初に処理してから続行確認したい」みたいな場面にピッタリです。

サンプル:税込み合計を何度でも計算する(do文の定番パターン)

ここでは、商品価格を入力して税込み価格を表示し、続けるかどうかを聞いて繰り返すプログラムを例に解説します。

プロジェクト名:chap4-1-1 ソースファイル名:chap4-1-1.c

Visual Studio でこのプログラムを実行するには、SDLチェック設定を変更しておく必要があります。
1.プロジェクト名を右クリックして、「プロパティ」をクリックします。
2.「C/C++」→「全般」→「SDLチェック」を「いいえ」に切り替えて「OK」をクリックします。

// 税込み価格を計算して、続けるか確認しながら繰り返すプログラム
#include <stdio.h>

int main(void)
{
    int again;                 // もう一度計算するか(1なら続行)
    const double tax = 0.10;   // 消費税率(10%)

    do {
        double price;
        double total;

        printf("Enter the price (JPY): ");
        scanf("%lf", &price);

        total = price * (1.0 + tax);

        printf("Total with tax: %.0f JPY\n", total);

        printf("Calculate another item? (Yes:1 / No:0): ");
        scanf("%d", &again);

    } while (again == 1);

    printf("Done. Have a nice day!\n");
    return 0;
}

実行例(イメージ)

Enter the price (JPY): 1200
Total with tax: 1320 JPY
Calculate another item? (Yes:1 / No:0): 1
Enter the price (JPY): 980
Total with tax: 1078 JPY
Calculate another item? (Yes:1 / No:0): 0
Done. Have a nice day!

do文の書式(構文)をしっかり確認

do文の基本形はこれです。

要素書き方役割
開始doループ開始を示す。
ループ本体文 または 複合文繰り返し実行する処理
条件判定while (式);式が真(非0)なら繰り返す。

do文の構文(イメージ)

do
    文(または { ... } の複合文)
while (式);

ポイント:最後にセミコロンが必要です。
while (式) の後ろに ; が付くのが、do文の見落としポイントになりがちです。

プログラムの流れ(図解):なぜ「必ず1回」動くの?

do文の流れはこうなります。

do文の制御フロー

(1) ループ本体を実行
      ↓
(2) 式を評価(制御式)
      ↓
  真(非0)なら (1) に戻る
  偽(0)なら ループ終了

この順番だから、条件が最初から偽でも1回は本体が実行されるんです。
今回の例なら、少なくとも1回は「価格入力 → 税込み計算 → 続けるか質問」まで進みます。

ループ本体・制御式・継続条件を言葉で整理

do文を読み解くときは、次の3つに分けて考えるとスッキリします。

用語意味サンプルでは
ループ本体繰り返される処理価格入力→計算→表示→続けるか質問
制御式繰り返すか判断する式again == 1
継続条件繰り返しを続ける条件again が 1 の間だけ続ける

今回の継続条件は again == 1 です。
ユーザーが 1 を入力したら継続、0 を入力したら終了。わかりやすいですね。

複合文内での宣言(スコープ):中でしか使わない変数は中で宣言する

サンプルでは、price や total を do の中(ブロックの中)で宣言しました。

do {
    double price;
    double total;
    ...
} while (again == 1);

これはすごく良い書き方で、理由はこうです。

  • その変数は ループの1回分の処理でしか使わない
  • ループの外に出すと、使える範囲が広がりすぎて混乱しやすい。
  • 「この変数はこの処理のためのもの」と意図が伝わる。

変数の有効範囲(ざっくり)

変数宣言場所使える範囲
againmainの中main関数内でずっと使える。
price / totaldoブロック内そのブロックの中だけ

この考え方は、規模が大きいプログラムほど効いてきます。
「使う場所の近くで宣言する」って、読みやすさが一気に上がるんですよね。

よくあるつまずき(do文あるある)

つまずき何が起きる?回避のコツ
while(式) の後ろの ; を忘れる。文法エラーになる。do-whileは最後に ; と覚える。
制御式を逆に書く続けたいのに止まる / 止めたいのに続く継続条件を日本語で言ってから式にする。
scanfの読み取り失敗変数が更新されず挙動が不安定入力形式(%d / %lf)を合わせる。

while文・for文との違い(ここだけ先取り)

今後学ぶ while / for と比べると、do文の立ち位置が見えます。

条件を確認するタイミング特徴
do文実行の後必ず1回は実行
while文実行の前条件が偽なら1回も実行されない。
for文実行の前(+回数管理しやすい)回数が決まっている繰り返しに強い。

「まずやらせて、あとで続けるか聞く」なら do文が自然、って感じです。

まとめ:do文を使うときの合言葉

do文は、

  • ループ本体をまず1回実行する。
  • その後に制御式を評価する。
  • 真(非0)なら繰り返す。

という流れでした。

合言葉にするなら、
「まず1回やってみて、続けるかは後で決める」 です。