
6日でできる 新C言語入門|複雑な if 文
複数の条件を、正しく・読みやすく組み立てる。
複雑な if 文を理解して、実践的な判断処理を書けるようになろう。
複雑な if 文
C言語の学習が進むと、単純な if 文だけでは表現しきれない場面が増えてきます。
たとえば、ある条件と別の条件が両方成り立つときだけ処理したい、複数の候補の中から状況に応じて細かく分岐したい、といったケースです。
このような場面で役立つのが、論理演算子を使った条件式や、if 文のネストです。
条件を組み合わせることで、プログラムはより柔軟に判断できるようになります。
ただし、条件を増やせば増やすほど、コードは分かりにくくなりやすいです。
そのため、複雑な if 文では、動作の正しさだけでなく、読みやすさや条件の並べ方もとても大切になります。
ここでは、論理演算子の基本、AND・OR・NOT の使い方、if 文のネスト、そして実践的な応用例まで、段階を追いながらやさしく解説していきます。
サンプルプログラムは、元の内容をベースにしながら別の題材にアレンジして紹介します。
複雑な if 文が必要になる理由
if 文は、条件が成り立つかどうかで処理を分ける基本構文です。
でも実際には、次のように1つの条件だけでは足りないことがよくあります。
| したいこと | 必要な考え方 |
|---|---|
| 両方の条件がそろったときだけ実行したい | AND |
| どちらか片方でも成り立てば実行したい | OR |
| 条件を反対の意味で判定したい | NOT |
| 大きな条件の中で、さらに細かく判定したい | ネスト |
| 入力値の範囲ごとに処理を変えたい | else if の連続 |
たとえば、次のような判断です。
- 2つの値がどちらも基準を満たしているか
- どちらか一方が条件を満たしているか
- 0ではないかどうか
- 会員かどうかを判定したあとで、購入金額に応じて送料を変える
- 点数の範囲によって評価を変える
このような処理をうまく書くために、複雑な if 文の考え方を身につけておくことが大切です。
論理演算子を使うと条件を組み合わせられる
複雑な if 文を書くときにまず覚えたいのが、論理演算子です。
論理演算子は、複数の条件をひとまとめにして判定するための記号です。
論理演算子の基本
| 演算子 | 名称 | 意味 | 使用例 | 例の意味 |
|---|---|---|---|---|
| && | 論理積 | 両方とも成り立つ | x >= 10 && y < 50 | xは10以上、かつyは50未満 |
| || | 論理和 | どちらか一方でも成り立つ | x == 0 || y == 0 | xまたはyが0 |
| ! | 否定 | 条件を反転する | !(x > 0) | xが正ではない |
&& は、条件Aも条件Bも両方とも真のときだけ真になります。
|| は、条件Aまたは条件Bのどちらか一方でも真なら真になります。
! は、真を偽に、偽を真にひっくり返します。
図:論理演算子で条件を組み合わせるイメージ

この図から分かること
この図から分かるのは、複雑な条件分岐では、1つの条件だけでなく、複数の条件を組み合わせて考えることが大切だという点です。
AND は両方の条件を満たす必要があり、OR はどちらか一方で十分です。
NOT は条件の意味を反転したいときに便利です。
この3つを使えるようになると、if 文で表現できる判断の幅がかなり広がります。
AND を使った複雑な if 文
AND は、両方の条件が成り立つときだけ真になる演算子です。
どちらか1つでも成り立たなければ、全体としては偽になります。
たとえば、午前と午後の気温が両方とも25度以上なら、暑い一日と判定するプログラムを考えてみましょう。
プロジェクト/ファイル名: Lesson22_1/main.c
#include <stdio.h>
int main(void) {
int morning_temp, afternoon_temp;
// 午前の気温を入力
printf("午前の気温を入力してください: ");
scanf("%d", &morning_temp);
// 午後の気温を入力
printf("午後の気温を入力してください: ");
scanf("%d", &afternoon_temp);
// 午前と午後の気温が両方とも25度以上か判定
if (morning_temp >= 25 && afternoon_temp >= 25) {
printf("一日を通して暑い日になりそうです。\n");
} else {
printf("どちらかの時間帯はそれほど暑くありません。\n");
}
return 0;
}実行結果
午前の気温を入力してください: 27
午後の気温を入力してください: 31
一日を通して暑い日になりそうです。
午前の気温を入力してください: 22
午後の気温を入力してください: 30
どちらかの時間帯はそれほど暑くありません。このプログラムでは、morning_temp >= 25 と afternoon_temp >= 25 の両方が真のときだけ、if の中の処理が実行されます。
AND の考え方を表で確認する
| morning_temp >= 25 | afternoon_temp >= 25 | 結果 |
|---|---|---|
| 真 | 真 | 一日を通して暑い日になりそうです |
| 真 | 偽 | どちらかの時間帯はそれほど暑くありません |
| 偽 | 真 | どちらかの時間帯はそれほど暑くありません |
| 偽 | 偽 | どちらかの時間帯はそれほど暑くありません |
AND は、どちらも満たしていることを確認したい場面に向いています。
たとえば、両方の点数が合格、会員かつ購入金額が一定以上、平日かつ営業時間内、というような条件でよく使います。
OR を使った複雑な if 文
OR は、どちらか一方でも条件が成り立てば真になる演算子です。
両方とも真でももちろん真ですが、片方だけ真でも全体として真になります。
次は、2つのテストのうちどちらか一方でも90点以上なら優秀と判定する例です。
プロジェクト/ファイル名: Lesson22_2/main.c
#include <stdio.h>
int main(void) {
int test1, test2;
// 1回目のテストの点数を入力
printf("1回目のテストの点数を入力してください: ");
scanf("%d", &test1);
// 2回目のテストの点数を入力
printf("2回目のテストの点数を入力してください: ");
scanf("%d", &test2);
// どちらか一方でも90点以上なら判定
if (test1 >= 90 || test2 >= 90) {
printf("少なくとも1回はとても良い成績です。\n");
} else {
printf("どちらの回も90点には届いていません。\n");
}
return 0;
}実行結果
1回目のテストの点数を入力してください: 92
2回目のテストの点数を入力してください: 68
少なくとも1回はとても良い成績です。
1回目のテストの点数を入力してください: 75
2回目のテストの点数を入力してください: 84
どちらの回も90点には届いていません。OR の考え方を表で確認する
| test1 >= 90 | test2 >= 90 | 結果 |
|---|---|---|
| 真 | 真 | 少なくとも1回はとても良い成績です |
| 真 | 偽 | 少なくとも1回はとても良い成績です |
| 偽 | 真 | 少なくとも1回はとても良い成績です |
| 偽 | 偽 | どちらの回も90点には届いていません |
OR は、条件のどれかを満たせばよい場面に向いています。
たとえば、会員またはクーポン所持、土曜日または日曜日、どちらかのセンサーが異常値、といった判定でよく使います。
NOT を使うと条件を反転できる
NOT は、条件の真偽を反転する演算子です。
条件が真なら偽に、偽なら真に変わります。
次の例では、入力された在庫数が0ではないかどうかを判定してみます。
プロジェクト/ファイル名: Lesson22_3/main.c
#include <stdio.h>
int main(void) {
int stock;
// 在庫数を入力
printf("在庫数を入力してください: ");
scanf("%d", &stock);
// 在庫が0でないかを判定
if (!(stock == 0)) {
printf("在庫があります。\n");
} else {
printf("在庫はありません。\n");
}
return 0;
}実行結果
在庫数を入力してください: 8
在庫があります。
在庫数を入力してください: 0
在庫はありません。この !(stock == 0) は、stock が 0 ではない、という意味です。
もちろん stock != 0 と書くこともできます。
初心者のうちは、NOT は意味が少し読み取りにくく感じることもあるので、条件が伝わりやすい書き方を選ぶのがおすすめです。
if 文のネストは段階的な判定に向いている
条件を1行にまとめるだけでなく、if 文の中にさらに if 文を書く方法もあります。
これを if 文のネスト、または入れ子構造といいます。
ネストは、まず大きな条件で分けて、その中でさらに細かく分岐したいときに便利です。
たとえば、
- まず会員かどうかを判定する
- 会員なら、その中で購入金額を判定する
- 非会員なら、別の基準で判定する
というように、段階的な判断を表現しやすくなります。
図:ネストした if 文の考え方

この図から分かること
この図から分かるのは、ネストした if 文は、1回の判定で終わらず、条件を段階的に確認していく構造だということです。
最初の条件で大きく分岐し、その結果に応じて次の条件を確認するため、複雑な判断を整理しやすくなります。
一方で、ネストが深くなりすぎると読みにくくなるので、必要以上に入り組ませない工夫も大切です。
ネストを使ったサンプルプログラム
次は、会員かどうかと購入金額によって送料を決めるプログラムです。
ネストした if 文を使うと、判定の流れが自然に書けます。
プロジェクト/ファイル名: Lesson22_4/main.c
#include <stdio.h>
int main(void) {
int member, total;
// 会員かどうかを入力
printf("会員ですか(1:はい, 0:いいえ): ");
scanf("%d", &member);
// 購入金額を入力
printf("購入金額を入力してください: ");
scanf("%d", &total);
// 会員かどうかで大きく分け、その中で金額を判定
if (member == 1) {
// 会員の場合の送料判定
if (total >= 3000) {
printf("会員特典により送料は無料です。\n");
} else {
printf("会員送料として200円かかります。\n");
}
} else {
// 非会員の場合の送料判定
if (total >= 5000) {
printf("購入金額により送料は無料です。\n");
} else {
printf("通常送料として500円かかります。\n");
}
}
return 0;
}実行結果
会員ですか(1:はい, 0:いいえ): 1
購入金額を入力してください: 3500
会員特典により送料は無料です。
会員ですか(1:はい, 0:いいえ): 0
購入金額を入力してください: 2800
通常送料として500円かかります。このプログラムでは、最初に会員かどうかで分かれます。
会員なら3000円以上かどうかを判定し、非会員なら5000円以上かどうかを判定します。
このように、大きな条件の中でさらに条件を分けたい場合、ネストはとても分かりやすい書き方です。
論理演算子とネストはどう使い分けるか
論理演算子でもネストでも、複雑な条件分岐は書けます。
どちらを使うかは、条件の意味や読みやすさで考えるのがポイントです。
| 書き方 | 向いている場面 |
|---|---|
| 論理演算子 | 1つの if 文でまとめて判定したいとき |
| ネスト | 段階的に条件を確認したいとき |
| else if | 範囲や候補ごとに順番に分岐したいとき |
たとえば、a >= 10 && b < 20 のように1つのまとまりとして読める条件なら、論理演算子が向いています。
一方で、まず会員かどうかを見て、そのあと購入金額を見るような段階的な判断なら、ネストのほうが自然です。
大切なのは、動けばよいではなく、後から見て理解しやすいことです。
複雑な if 文の応用例
ここからは、論理演算子と else if を組み合わせた、少し実践的な例を見てみましょう。
入力された点数が正しい範囲かどうかも確認しつつ、評価を分けるプログラムです。
プロジェクト/ファイル名: Lesson22_5/main.c
#include <stdio.h>
int main(void) {
int score;
// 点数を入力
printf("試験の点数を入力してください: ");
scanf("%d", &score);
// 点数の範囲を確認しながら評価を判定
if (score < 0 || score > 100) {
printf("0点から100点までの範囲で入力してください。\n");
} else if (score >= 80) {
printf("評価はAです。\n");
} else if (score >= 60) {
printf("評価はBです。\n");
} else if (score >= 40) {
printf("評価はCです。\n");
} else {
printf("評価はDです。\n");
}
return 0;
}実行結果
試験の点数を入力してください: 88
評価はAです。
試験の点数を入力してください: 54
評価はCです。
試験の点数を入力してください: 120
0点から100点までの範囲で入力してください。このプログラムでは、最初に score < 0 || score > 100 で入力値が不正かどうかをチェックしています。
ここで OR を使っているのは、0未満または100超のどちらかに当てはまれば不正としたいからです。
そのあとに else if で点数の範囲を順番に判定しています。
このように、複数の考え方を組み合わせることで、より実用的な条件分岐が書けます。
図:複雑な if 文を整理して考える流れ

この図から分かること
この図から分かるのは、複雑な if 文は、いきなり細かい評価に進むのではなく、先に入力チェックをしてから段階的に判定すると整理しやすいということです。
まず不正な入力を弾き、そのあとで範囲ごとの評価に進むと、条件の役割がはっきりします。
複雑な条件ほど、判定の順番を意識することが大切です。
複雑な if 文でよくある間違い
複雑な if 文では、文法ミスだけでなく、条件の考え方そのものを間違えてしまうことがあります。
よくあるポイントを押さえておきましょう。
条件の優先順位を考えずに書いてしまう
条件の順番が悪いと、本来あとで判定したい条件に到達しません。
たとえば、
if (score >= 40) {
printf("C以上です。\n");
} else if (score >= 80) {
printf("Aです。\n");
}この書き方だと、80点以上でも最初の score >= 40 が真になってしまい、Aの判定まで進みません。
括弧を省略しすぎて読みにくくなる
複数の条件を組み合わせるときは、意味がはっきり伝わるように丸括弧を付けると安心です。
たとえば、
if ((x >= 10 && x <= 20) || y == 0)のように書くと、どの条件がまとまりなのかが見やすくなります。
ネストが深くなりすぎる
if の中に if、その中にさらに if、と深くしすぎると、コードがとても読みにくくなります。
3段、4段と深くなる場合は、条件を整理し直したり、別の書き方にできないか考えるとよいです。
! の意味を見失いやすい
NOT は便利ですが、否定が重なると読み取りづらくなります。
たとえば、
if (!(value != 0))は動作としては間違いではありませんが、かなり分かりにくいです。
この場合は value == 0 と書いたほうがすっきりします。
読みやすい複雑な if 文を書くコツ
複雑な if 文は、正しく動くことに加えて、読みやすく書くことがとても大事です。
読みやすさを意識するだけで、バグを防ぎやすくなります。
| コツ | 内容 |
|---|---|
| 条件を日本語で言い換えてから書く | 先に意味を整理するとミスが減る |
| 条件の順番を意識する | 厳しい条件や特別な条件を先に書く |
| 丸括弧を適度に使う | 条件のまとまりが見やすくなる |
| ネストを深くしすぎない | 必要以上に入り組ませない |
| 入力チェックを先に行う | 不正値を早めに処理できる |
| インデントを整える | どこがどの if に対応しているか分かりやすい |
たとえば、点数判定なら、まず不正値かどうか、次に高い評価から順番に判定する、というように流れを決めておくと書きやすくなります。
scanf を使うときの補足
今回のサンプルでは、入力処理に scanf を使っています。
Visual Studio 系の開発環境では、scanf に対して警告が出ることがあります。学習用のコードではよく使われますが、環境によっては SDL チェックや安全性に関する設定の影響を受けることがあります。
ただ、ここで大切なのは、複雑な if 文の考え方です。
scanf 自体の細かい扱いよりも、入力された値をどのように判定して分岐させるかに注目して学ぶと理解しやすいです。
複雑な if 文は実践力につながる
単純な if 文を覚えたあと、論理演算子やネストを理解できるようになると、書けるプログラムの幅が一気に広がります。
たとえば、
- 条件を組み合わせた厳密な判定
- 入力値のチェック
- 複数段階の評価分岐
- 状況に応じた細かな処理切り替え
といった、実用的なプログラムの土台が作れるようになります。
複雑な if 文は、少し難しく感じるかもしれませんが、基本はシンプルです。
1つずつ条件の意味を確認し、どの順番で判定するかを丁寧に考えれば、必ず整理できます。
まずは AND、OR、NOT の基本を押さえ、そのあとでネストや else if を組み合わせる練習をしてみてください。
条件を日本語で説明できるくらいまで理解できると、コードもぐっと読みやすく書けるようになります。
