
C言語の基本|条件式の反転
条件の向きを変えれば、コードの見え方も変わる。真と偽を入れ替えて、意図が伝わる分岐を作ろう。
if~else文は、条件式が真ならif側、偽ならelse側を実行する制御文です。この条件式を反対の意味に書き換えると、if側とelse側の役割を入れ替えられます。
たとえば、音量設定が0以上20以下なら正常、それ以外ならエラーと判定する場合、次の2通りで表現できます。
- 正常な範囲をif側で判定する
- 範囲外をif側で判定する
どちらも同じ結果にできます。大切なのは、正常と異常のどちらを先に見せると、処理の目的が伝わりやすいかという点です。
条件式を反転する代表的な方法は次の2つです。
- 比較演算子や論理演算子を反対の形へ書き換える
- 否定演算子!を使って条件式全体を反転する
図1:条件式を反転してif側とelse側を入れ替える

この図から分かること
正常な範囲をif側へ置く書き方と、範囲外をif側へ置く書き方では、条件式の真と偽が入れ替わります。
ただし、同じ動作を保つには、条件式を反転するだけでなく、ifブロックとelseブロックの処理も入れ替える必要があります。
| 書き方 | if側 | else側 |
|---|---|---|
| 正常な条件を判定 | 正常時の処理 | 異常時の処理 |
| 異常な条件を判定 | 異常時の処理 | 正常時の処理 |
条件式を反転するメリット
条件式を反転すると、重要な処理をif側へ移動できます。
たとえば、入力値を検査するプログラムでは、次のどちらの構成も考えられます。
- 正常な入力を先に判定する
- 異常な入力を先に判定する
正常な処理を中心に見せたい場合は、正常条件をif側へ置くと自然です。入力ミスや範囲外の値を強調したい場合は、異常条件をif側へ置くと目的が伝わりやすくなります。
範囲内をif側に置く書き方
最初は、正常な範囲を条件式にします。
音量設定値が0以上20以下なら有効とする場合、条件は次の2つです。
- volume >= 0
- volume <= 20
両方を満たす必要があるため、&&で接続します。
音量設定値が有効な範囲かを判定するプログラム
ファイル名:8_5_1.c
#include <stdio.h>
int main(void)
{
int volume;
printf("音量設定値を入力してください(0~20)> ");
scanf("%d", &volume);
/* 有効な範囲をif側で判定する */
if (volume >= 0 && volume <= 20) {
printf("音量設定値は有効です。\n");
} else {
printf("音量設定値は範囲外です。\n");
}
return 0;
}実行結果の例
音量設定値を入力してください(0~20)> 12
音量設定値は有効です。プログラムの詳しい解説
条件式は、volumeが0以上であり、さらに20以下であるかを確認しています。
volume >= 0 && volume <= 2012を入力すると、12は0以上であり、20以下でもあります。2つの条件がどちらも真になるため、ifブロックが実行されます。
一方、25を入力するとvolume <= 20が偽になるため、条件式全体も偽になり、elseブロックが実行されます。
0と20も有効な値に含めたいので、下限には>=、上限には<=を使用しています。
範囲外をif側に置く書き方
次は、同じ判定を反転し、範囲外の条件をif側へ置きます。
0以上20以下の範囲から外れるのは、次のどちらかの場合です。
- 0未満である
- 20より大きい
どちらか一方に該当すれば範囲外なので、||で接続します。
範囲外の音量設定値を先に検出するプログラム
ファイル名:8_5_2.c
#include <stdio.h>
int main(void)
{
int volume;
printf("音量設定値を入力してください(0~20)> ");
scanf("%d", &volume);
/* 範囲外をif側で判定する */
if (volume < 0 || volume > 20) {
printf("音量設定値は範囲外です。\n");
} else {
printf("音量設定値は有効です。\n");
}
return 0;
}実行結果の例
音量設定値を入力してください(0~20)> 25
音量設定値は範囲外です。プログラムの詳しい解説
条件式は、volumeが0未満、または20より大きいかを調べています。
volume < 0 || volume > 2025を入力するとvolume > 20が真になるため、ifブロックが実行されます。
12を入力した場合は、volume < 0とvolume > 20が両方とも偽になります。||でつないだ条件は、両方が偽のときに全体が偽になるため、elseブロックへ進みます。
8_5_1.cと8_5_2.cでは、条件式の向きとブロックの順番が異なりますが、入力に対する判定結果は同じです。
&&と||が入れ替わる理由
範囲内の条件では、下限と上限の両方を満たす必要があります。
volume >= 0 && volume <= 20範囲外では、下限より小さいか、上限より大きいかのどちらかに該当すれば十分です。
volume < 0 || volume > 20比較すると、次の部分が反転しています。
| 範囲内の条件 | 範囲外の条件 |
|---|---|
| volume >= 0 | volume < 0 |
| volume <= 20 | volume > 20 |
| 2つとも必要なので&& | どちらかで範囲外なので|| |
図2:数直線で見る範囲内と範囲外

この図から分かること
範囲内は0から20までの連続した部分です。この部分に入るには、0以上と20以下の両方を満たさなければなりません。
範囲外は数直線の左右に分かれています。0未満か20より大きいかのどちらかに該当すれば範囲外なので、||を使います。
否定演算子!で条件式全体を反転する
比較演算子を一つずつ書き換えず、条件式の前に!を付けて反転することもできます。
!(volume >= 0 && volume <= 20)丸括弧内は、volumeが0以上20以下という範囲内の条件です。その前に!を付けることで、範囲内ではないという意味になります。
!は直後の条件を否定する演算子です。複数の条件をまとめて反転するときは、対象となる条件式全体を丸括弧で囲みます。
否定演算子で音量の範囲外を判定するプログラム
ファイル名:8_5_3.c
#include <stdio.h>
int main(void)
{
int volume;
printf("音量設定値を入力してください(0~20)> ");
scanf("%d", &volume);
/* 範囲内の条件全体を!で否定する */
if (!(volume >= 0 && volume <= 20)) {
printf("音量設定値は範囲外です。\n");
} else {
printf("音量設定値は有効です。\n");
}
return 0;
}実行結果の例
音量設定値を入力してください(0~20)> -3
音量設定値は範囲外です。プログラムの詳しい解説
-3はvolume >= 0を満たさないため、丸括弧内の条件式は偽になります。
その偽を!で反転すると真になるので、ifブロックが実行されます。
反対に10を入力した場合、丸括弧内は真です。!によって偽へ反転されるため、elseブロックが実行されます。
次の2つの条件式は同じ意味です。
!(volume >= 0 && volume <= 20)
volume < 0 || volume > 20!を使うと条件全体をそのまま反転できます。ただし、否定や丸括弧が多くなると読み取りにくくなることもあります。範囲外を直接書いたほうが分かりやすい場合は、volume < 0 || volume > 20を選んでも構いません。
比較演算子を反転する基本ルール
比較演算子には、それぞれ反対の意味になる組み合わせがあります。
| 元の条件 | 反転した条件 | 意味 |
|---|---|---|
| A == B | A != B | 等しいを等しくないへ反転 |
| A != B | A == B | 等しくないを等しいへ反転 |
| A < B | A >= B | より小さいを以上へ反転 |
| A <= B | A > B | 以下をより大きいへ反転 |
| A > B | A <= B | より大きいを以下へ反転 |
| A >= B | A < B | 以上をより小さいへ反転 |
たとえばage < 20を反転すると、age >= 20になります。
20未満ではない範囲には20も含まれるため、単純にage > 20へ変えるのではありません。境界値がどちらに含まれるかを確認することが大切です。
論理演算子を反転するルール
複数の条件をまとめて反転すると、&&と||も入れ替わります。
| 元の条件 | 反転した条件 |
|---|---|
| A && B | !A || !B |
| A || B | !A && !B |
これは、次のように読み替えると理解しやすくなります。
- AとBを両方満たすのではない
- Aを満たさない、またはBを満たさない
- AかBのどちらかを満たすのではない
- AもBも満たさない
実際の範囲条件に当てはめると、次のようになります。
!(value >= 10 && value <= 30)この条件は、次の条件と同じ意味です。
value < 10 || value > 30範囲内をif側に置いた料金判定
次は、年齢が指定範囲内であることをif側で判定します。
ここでは、博物館のジュニア料金を6歳以上18歳以下の利用者に適用するものとします。
ジュニア料金の対象年齢を判定するプログラム
ファイル名:8_5_4.c
#include <stdio.h>
int main(void)
{
int age;
printf("年齢を入力してください > ");
scanf("%d", &age);
/* 6歳以上18歳以下ならジュニア料金の対象 */
if (age >= 6 && age <= 18) {
printf("ジュニア料金の対象です。\n");
} else {
printf("ジュニア料金の対象ではありません。\n");
}
return 0;
}実行結果の例
年齢を入力してください > 18
ジュニア料金の対象です。プログラムの詳しい解説
ジュニア料金の条件は6歳以上18歳以下なので、条件式は次のようになります。
age >= 6 && age <= 18下限の6歳を含めるために>=を使い、上限の18歳も含めるために<=を使っています。
さらに、下限と上限の両方を満たす必要があるので、2つの条件を&&でつないでいます。
18を入力した場合、age >= 6とage <= 18はどちらも真です。そのため、ジュニア料金の対象としてifブロックが実行されます。
範囲外をif側に置いた利用時間判定
今度は、利用できない時間帯をif側で先に判定します。
施設を利用できる時間帯を9時以上18時未満とすると、利用時間外は次のようになります。
- 9時未満
- 18時以上
利用時間外を先に判定するプログラム
ファイル名:8_5_5.c
#include <stdio.h>
int main(void)
{
int hour;
printf("利用開始時刻を整数で入力してください > ");
scanf("%d", &hour);
/* 利用可能時間は9時以上18時未満 */
if (hour < 9 || hour >= 18) {
printf("現在は利用時間外です。\n");
} else {
printf("現在は利用可能な時間です。\n");
}
return 0;
}実行結果の例
利用開始時刻を整数で入力してください > 18
現在は利用時間外です。プログラムの詳しい解説
利用可能な時間を先に書くと、次の条件になります。
hour >= 9 && hour < 18この条件を反転すると、利用時間外の条件になります。
hour < 9 || hour >= 18利用可能な条件では18時未満となっているため、18時は含まれません。その反対側ではhour >= 18となり、18時を利用時間外に含めます。
| 入力時刻 | 判定 | 実行される側 |
|---|---|---|
| 8 | 利用時間外 | if |
| 9 | 利用可能 | else |
| 17 | 利用可能 | else |
| 18 | 利用時間外 | if |
図3:境界を含めて条件を反転する流れ

この図から分かること
条件式を反転するときは、演算子の向きだけでなく、境界値をどちらに含めるかも変化します。
hour < 18の反転はhour > 18ではなく、hour >= 18です。18未満ではない範囲には18も含まれるからです。
また、利用可能な条件では下限と上限の両方を満たすため&&を使いますが、利用時間外ではどちらか一方に該当すればよいため||を使います。
複数の条件を組み合わせたうるう年判定
うるう年の判定では、複数の条件を&&と||で組み合わせます。
判定基準は次のとおりです。
- 400で割り切れる年はうるう年
- 400で割り切れなくても、4で割り切れて100で割り切れない年はうるう年
- それ以外は平年
1年の日数をうるう年の条件から判定するプログラム
ファイル名:8_5_6.c
#include <stdio.h>
int main(void)
{
int year;
printf("西暦年を入力してください > ");
scanf("%d", &year);
/* うるう年なら366日、平年なら365日と表示する */
if ((year % 400 == 0) ||
(year % 4 == 0 && year % 100 != 0)) {
printf("%d年はうるう年で、1年は366日です。\n", year);
} else {
printf("%d年は平年で、1年は365日です。\n", year);
}
return 0;
}実行結果の例
400で割り切れる年を入力した場合は、うるう年になります。
西暦年を入力してください > 2000
2000年はうるう年で、1年は366日です。100で割り切れても400で割り切れない年は、平年になります。
西暦年を入力してください > 2100
2100年は平年で、1年は365日です。プログラムの詳しい解説
最初の条件は、yearが400で割り切れるかを調べています。
year % 400 == 02000は400で割り切れるため、この条件だけでうるう年と判定できます。
もう一方では、4で割り切れることと100で割り切れないことを&&で組み合わせています。
year % 4 == 0 && year % 100 != 0この2つのうるう年条件は、どちらか一方を満たせばよいため、||で接続します。
(year % 400 == 0) ||
(year % 4 == 0 && year % 100 != 0)2100は4で割り切れますが、100でも割り切れます。また、400では割り切れません。したがって、うるう年の条件式全体が偽になり、elseブロックが実行されます。
条件式が長くなる場合は、意味のまとまりごとに丸括弧を付けると読みやすくなります。どの条件を&&でまとめ、どのまとまりを||で接続しているのかが見えやすくなり、反転や修正をするときの間違いも防ぎやすくなります。
