C言語のきほん|if文のネスト構造

条件が増えても迷わない。if文を“階段”みたいに組み立てて、判断をスッキリ整理しよう。

プログラムって、だいたい「状況に応じてやることを変える」場面だらけです。
たとえば、

  • 入力が正しいなら処理を進めたい(正しくないならエラーにしたい)
  • 正しい入力の中でも、さらに条件で分けたい(Aならこれ、Bならあれ…)

こういうときに便利なのが if文のネスト構造(入れ子) です。

ネスト構造は、ざっくり言うと 「大きい条件の中に、もう一段細かい条件を入れる」 という考え方です。
最初に「この道に入っていい?」をチェックして、OKなら「じゃあ次はどっち?」を判断する、みたいなイメージですね。

入れ子(ネスト)構造とは

入れ子(ネスト)構造とは、1つの制御構造の中に、同じ種類の制御構造を組み込むことです。
if文なら、ifの中にifを書くことで「段階的な判定」ができます。

イメージ(ざっくり図)

文法:if文の入れ子(基本形)

if (条件式1) {
    if (条件式2) {
        文1;
    } else {
        文2;
    }
} else {
    文3;
}

条件と実行される処理の対応

条件式1条件式2実行される処理
文1
文2
(見ない)文3

ポイントはここです👇
条件式1が偽なら、条件式2は判定すらされません。(内側に入らないから)

if~else if~else~も「ネストの仲間」

if~else if~else~は「条件を順番にチェック」しますが、見方によってはこういう構造です。

  • 「最初の条件がダメなら次」
  • 「次もダメならその次」
  • 「全部ダメなら最後」

これも広い意味で「条件を段階化している」ので、ネスト的な考え方につながっています。

ネストを使うときの注意点(読みやすさが命)

ネストは強力ですが、深くなりすぎると一気に読みにくくなります。そこで、定番の注意点をしっかり押さえましょう。

読みやすくするコツ

注意点なぜ大事?実践のコツ
インデントを揃える階層が見えないと事故る1段下げを徹底(スペース4つなど)
波括弧 {} を省略しない1行ifのつもりがバグになる教材では特に必ず付ける
深いネストを避ける脳内スタックが溢れる先にエラーを弾く(ガード節)や、条件を整理する

サンプルプログラム

「所持金が正しい範囲か確認 → その上で“買える飲み物”を判定」するプログラム例です。

仕様

  • 所持金 money(0〜1000円)以外はエラー
  • 0〜1000円の範囲なら、買えるものを判定
    ・500円以上:コーヒー
    ・200円以上:お茶
    ・それ未満:水

ファイル名:8_7_1.c

// if文の入れ子を使って「所持金に応じた飲み物」を判定するプログラム
#include <stdio.h>

int main(void)
{
    int money;

    printf("所持金を入力してください(0~1000)> ");
    scanf("%d", &money);

    // まずは入力が有効かどうか(外側のif)をチェック
    if (money >= 0 && money <= 1000) {

        // 入力が有効な場合だけ、買えるものを判定(内側のif)
        if (money >= 500) {
            printf("コーヒーが買えます。\n");
        }
        else if (money >= 200) {
            printf("お茶が買えます。\n");
        }
        else {
            printf("水なら買えます。\n");
        }

    } else {
        printf("入力エラー:0~1000の範囲で入力してください。\n");
    }

    return 0;
}

ここが「ネストの気持ちいいところ」

  • 外側:入力の正当性チェック(不正なら即エラー)
  • 内側:正しい入力のときだけ、細かい判定

つまり、関係のある条件を内側にまとめて、処理の流れを整理できるわけです。

どこがネスト?処理の流れを図にするとこう

「エラー判定を先にする」発想がネストと相性抜群

提示文にもあった通り、エラー判定を先にしてから中で本処理って形は、ネストがすごく自然になります。

なぜ先にエラーを弾くと良い?

  • 正常系の処理だけを内側に集められる
  • 不正入力のときに、余計な判定をしなくて済む
  • 「まず入口チェック→入ったら中で分岐」になって読みやすい

実践問題

購入金額と学生かどうかを入力して、割引額を表示するプログラムを作成してください。
if文のネストで書きましょう。

割引ルール

  • 学生の場合
    ・5000円以上:15%割引
    ・5000円未満:8%割引
  • 学生でない場合
    ・5000円以上:8%割引
    ・5000円未満:割引なし

入力条件

  • 購入金額は0以上(負の値はエラー)
  • 学生入力は 1(はい)か 0(いいえ)以外はエラー

実行結果例1(5000円以上の学生)

購入金額を入力してください(円)> 6000
学生ですか?(1:はい、0:いいえ)> 1
割引額は 900円です。
支払金額は 5100円です。

実行結果例2(5000円未満の非学生)

購入金額を入力してください(円)> 3000
学生ですか?(1:はい、0:いいえ)> 0
割引額は 0円です。
支払金額は 3000円です。

解答例

ファイル名:8_7_2.c

// if文の入れ子を使って「学生割引」を計算するプログラム
#include <stdio.h>

int main(void)
{
    int price;
    int is_student;
    int discount;
    int pay;

    printf("購入金額を入力してください(円)> ");
    scanf("%d", &price);

    printf("学生ですか?(1:はい、0:いいえ)> ");
    scanf("%d", &is_student);

    // まず入力チェック(外側のif)
    if (price >= 0 && (is_student == 0 || is_student == 1)) {

        // 入力が正しい場合だけ、割引ルール判定(内側のif)
        if (is_student == 1) {
            // 学生の場合
            if (price >= 5000) {
                discount = price * 15 / 100;
            } else {
                discount = price * 8 / 100;
            }
        } else {
            // 学生ではない場合
            if (price >= 5000) {
                discount = price * 8 / 100;
            } else {
                discount = 0;
            }
        }

        pay = price - discount;

        printf("割引額は %d円です。\n", discount);
        printf("支払金額は %d円です。\n", pay);

    } else {
        printf("入力エラー:金額は0以上、学生は1か0で入力してください。\n");
    }

    return 0;
}

解説:ネストの分け方が「ルールの分岐」と一致してる

ここ、設計として気持ちいいポイントです。

  • 外側:入力が正しいか(ここが崩れると計算自体が無意味)
  • 内側:割引ルールの分岐
    ・まず「学生かどうか」
    ・その中で「5000円以上かどうか」

条件の階層(整理図)

ネストは「適当に入れる」んじゃなくて、ルールの階層に合わせて入れると読みやすくなります。