C言語基礎|ネストしたif文

ネストしたif文とは何か

これまで学習してきた if 文は、条件によって 処理を分岐させるための文 でしたね。
基本形は次の2つです。

形式意味
if(式)文条件が成立したときだけ処理する。
if(式)文 else 文条件に応じて処理を切り替える。

ここで重要なのは、if 文そのものも1つの「文」 だという点です。
つまり、

else が制御する「文」の中に、さらに if 文を書いてもよい

ということになります。

このように if 文の中に if 文を書く構造
ネストしたif文(入れ子のif文) と呼びます。

ネストが必要になる場面

現実の判断は、たいてい 一段階では終わりません

たとえば次のような判断です。

  • 入力された数値が 正の数かどうか
  • 正の数であれば、さらに 大きいか小さいか
  • 条件を満たさない場合は、別のメッセージを出す

このような 段階的な判断 を行うとき、ネストしたif文がとても自然な形になります。

ネストしたif文の基本構造

まずは構造をそのまま見てみましょう。

if (条件1)
    文A;
else
    if (条件2)
        文B;
    else
        文C;

この形では、

  • 条件1 が成立 → 文A
  • 条件1 が不成立で、条件2 が成立 → 文B
  • 条件1 も条件2 も不成立 → 文C

という 3分岐 が実現されています。

サンプルプログラム

ここでは、

入力された整数が
・0
・正の数
・負の数
のどれに該当するかを表示する

のどれに当たるかを判定するプログラムに置き換えます。

プログラム例

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

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

#include <stdio.h>

int main(void)
{
    int num;

    printf("整数を入力してください:");
    scanf("%d", &num);

    if (num == 0)
        puts("入力された値はゼロです。");
    else
        if (num > 0)
            puts("入力された値は正の数です。");
        else
            puts("入力された値は負の数です。");

    return 0;
}

実行イメージ

入力表示
0入力された値はゼロです。
12入力された値は正の数です。
-5入力された値は負の数です。

if文の流れ

このプログラムでは、必ずどれか1つだけ が実行されます。

  • 何も表示されないことはない。
  • 複数のメッセージが同時に表示されることもない。

これは、if 文が 排他的に処理を選ぶ構造 だからです。

ネストしたif文の特徴

特徴説明
上位の条件が最優先外側の if が最初に評価される
内側は次の判断外側が成立しなかった場合のみ評価
表示は必ず1つ条件が重ならないため

else if は特別な構文ではない

C言語では、

else if (条件)

という書き方をよく見かけますが、
これは 特別な文法ではありません

実体は次の形と 完全に同じ です。

else
    if (条件)

読みやすさのために 1 行で書いているだけ、という理解で大丈夫です。

複合文を使うと読みやすくなる

ネストが深くなると、どの else がどの if に対応しているのか
分かりにくくなることがあります。

そんなときは 複合文({ }) を使いましょう。

if (value == 0) {
    puts("入力された値はゼロです。");
} else {
    if (value > 0) {
        puts("入力された値は正の数です。");
    } else {
        puts("入力された値は負の数です。");
    }
}

複合文のメリット

ポイント効果
対応関係が明確if と else の結びつきが分かる。
バグを防げる意図しない else を防止
学習段階に最適構造の理解が深まる。

演習問題

演習3-2

次の条件分岐を考えなさい。

  • 整数が 0 のとき
    → 「ゼロが入力されました」
  • 整数が負のとき
    → 「負の数が入力されました」
  • 上記以外
    → 「正の数が入力されました」

このとき、最後の else を
else if (num > 0)
に変更した場合、動作に違いがあるかを確認せよ。

解答例

プロジェクト名:chap3-6-2 ソースファイル名:chap3-6-2.c

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

#include <stdio.h>

int main(void)
{
    int num;

    printf("整数を入力してください:");
    scanf("%d", &num);

    if (num == 0)
        puts("ゼロが入力されました。");
    else if (num < 0)
        puts("負の数が入力されました。");
    else
        puts("正の数が入力されました。");

    return 0;
}

解説
この場合、条件がすべて明示されているため、
元のネスト構造と同じ結果になります。

演習3-3

整数を読み込み、

  • 正の数 → そのまま表示
  • 負の数 → 符号を反転して表示
  • 0 → 0 と表示

するプログラムを作成せよ。

解答例

プロジェクト名:chap3-6-3 ソースファイル名:chap3-6-3.c

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

#include <stdio.h>

int main(void)
{
    int n;

    printf("整数を入力してください:");
    scanf("%d", &n);

    if (n > 0)
        printf("値は%dです。\n", n);
    else
        if (n < 0)
            printf("値は%dです。\n", -n);
        else
            puts("値は0です。");

    return 0;
}

解説
条件を段階的に判定することで、
0・正・負を明確に分けています。

演習3-4

プロジェクト名:chap3-6-4 ソースファイル名:chap3-6-4.c

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

二つの整数 A と B を読み込み、

  • A と B が等しい
  • A が B より大きい
  • A が B より小さい

のいずれかを表示するプログラムを作成せよ。

解答例

#include <stdio.h>

int main(void)
{
    int a, b;

    printf("整数A:");
    scanf("%d", &a);
    printf("整数B:");
    scanf("%d", &b);

    if (a == b)
        puts("AとBは同じ値です。");
    else
        if (a > b)
            puts("AはBより大きいです。");
        else
            puts("AはBより小さいです。");

    return 0;
}

解説
3つの条件を 排他的に処理できている点が重要です。

まとめ:ネストしたif文の考え方

  • if 文は「文」なので、他の if 文の中に書ける。
  • 段階的な条件判断にとても向いている。
  • else if は、実体としては if 文の入れ子
  • 複合文を使うと、可読性と安全性が高まる。