C言語の基本|論理演算子の使い方

複数の条件も、&&・||・!で分かりやすく整理。論理演算子を使い分けて、狙いどおりの判定を作ろう。

if文を使うと、条件が真の場合だけ特定の処理を実行できます。しかし、実際のプログラムでは、1つの条件だけでは判定できないことがあります。

たとえば、次のような条件です。

  • 画面の明るさが0以上かつ100以下である
  • 入力値が0未満または100より大きい
  • 条件を満たしていない場合だけ警告する
  • 三角形を作るためのすべての条件を満たしている
  • ある整数が指定した数で割り切れない

このような複数の条件を組み合わせるときに使うのが論理演算子です。

C言語でよく使う論理演算子は、次の3つです。

  • &&は、2つの条件が両方とも真か判定する
  • ||は、2つの条件のどちらかが真か判定する
  • !は、条件の真と偽を反転する

論理演算子を使うと、範囲内、範囲外、複数条件の同時成立などを1つの条件式で表現できます。

論理演算子とは

論理演算子は、条件式の真と偽を組み合わせるための演算子です。

論理演算子名前意味真になる条件
&&論理積AかつBAとBの両方が真
||論理和AまたはBAとBのどちらか一方以上が真
!論理否定AではないAが偽

&&は、すべての条件を満たす必要がある場合に使います。

||は、複数の条件のうち、どれか1つでも満たせばよい場合に使います。両方が真の場合も、全体は真になります。

!は、条件式の結果を反転します。真に!を付けると偽になり、偽に!を付けると真になります。

&&と||の真理値表

AとBを、それぞれ真または偽になる条件式とします。

ABA && BA || B
0000
0101
1001
1111

&&は、AとBが両方とも1の場合だけ1になります。

||は、AとBのどちらか一方、または両方が1なら1になります。両方とも0の場合だけ0です。

!の真理値表

!は、1つの条件式に対して使用します。

A!A
01
10

Aが偽なら!Aは真になります。Aが真なら!Aは偽になります。

C言語では0が偽、0以外が真として扱われます。論理演算子による式の結果は、真なら1、偽なら0になります。

図1:&&・||・!の判定ルール

この図から分かること

&&は、組み合わせた条件がすべて真の場合だけ、全体を真にします。

||は、どれか1つでも条件が真なら、全体を真にします。両方の条件が真の場合も、全体は真です。

!は条件を追加する演算子ではなく、1つの条件式の結果を反転する演算子です。

&&は両方の条件を満たす場合に使う

&&は、複数の条件をすべて満たす必要がある場合に使います。

たとえば、ディスプレイの明るさとして0から100までを有効な範囲にするとします。

この条件は、次の2つに分けられます。

  • brightnessが0以上である
  • brightnessが100以下である

両方の条件を満たす必要があるため、&&でつなぎます。

brightness >= 0 && brightness <= 100
brightness0以上100以下全体の判定
-10
0
50
100
120

0と100は範囲内に含まれます。そのため、下限には>=、上限には<=を使います。

範囲内の条件を数直線で考える

0以上100以下の範囲は、数直線上では0から100までの間です。

&&を使った範囲判定では、下限条件と上限条件が重なる部分が真になります。

  • brightness >= 0が表す範囲は0以上
  • brightness <= 100が表す範囲は100以下
  • 2つの範囲が重なる0から100が有効範囲

複数の条件を作るときは、それぞれが表す範囲を考えると、&&と||を選びやすくなります。

&&を使って範囲内を判定する

画面の明るさが0から100の範囲内か判定するプログラム

ファイル名:8_3_1.c

#include <stdio.h>

int main(void)
{
    int brightness;

    printf("画面の明るさを入力してください(0~100)> ");
    scanf("%d", &brightness);

    /* 0以上かつ100以下なら有効な範囲 */
    if (brightness >= 0 && brightness <= 100) {
        printf("入力された明るさは有効な範囲です。\n");
    }

    return 0;
}
実行結果の例
画面の明るさを入力してください(0~100)> 72
入力された明るさは有効な範囲です。
範囲内を判定するプログラムの詳しい解説

brightnessには、入力された画面の明るさを保存します。

記述役割
int brightness;明るさを保存する変数を宣言する
scanf("%d", &brightness);入力された整数をbrightnessへ保存する
brightness >= 0明るさが下限の0以上か判定する
brightness <= 100明るさが上限の100以下か判定する
&&2つの条件が両方とも真か判定する
printf範囲内の場合だけメッセージを表示する

72を入力した場合、brightness >= 0とbrightness <= 100は両方とも真です。そのため、&&で組み合わせた条件式全体も真になります。

  • 72 >= 0は真
  • 72 <= 100は真
  • 真 && 真は真

条件式全体が真になるため、ifのブロック内が実行されます。

||はどちらかの条件を満たす場合に使う

||は、複数の条件のどれか1つでも満たした場合に、全体を真にする論理演算子です。

画面の明るさが有効範囲の外側にある条件を考えます。

0から100の範囲外になるのは、次のどちらかです。

  • brightnessが0未満である
  • brightnessが100より大きい

どちらか一方に該当すれば範囲外なので、||でつなぎます。

brightness < 0 || brightness > 100
brightness0未満100より大きい全体の判定
-10
0
50
100
120

-10の場合は最初の条件が真なので、全体も真です。

120の場合は2番目の条件が真なので、全体も真です。

50の場合は両方の条件が偽なので、全体も偽です。

||を使って範囲外を判定する

画面の明るさが範囲外なら警告するプログラム

ファイル名:8_3_2.c

#include <stdio.h>

int main(void)
{
    int brightness;

    printf("画面の明るさを入力してください(0~100)> ");
    scanf("%d", &brightness);

    /* 0未満または100より大きければ範囲外 */
    if (brightness < 0 || brightness > 100) {
        printf("警告: 明るさが有効範囲の外です。\n");
    }

    return 0;
}
実行結果の例
画面の明るさを入力してください(0~100)> 135
警告: 明るさが有効範囲の外です。
範囲外を判定するプログラムの詳しい解説

このプログラムでは、0未満と100より大きいという2つの条件を||で組み合わせています。

135を入力した場合は、次の結果になります。

  • 135 < 0は偽
  • 135 > 100は真
  • 偽 || 真は真

どちらか一方が真なので、条件式全体も真です。そのため、範囲外の警告が表示されます。

0から100までの値を入力した場合は、2つの条件が両方とも偽になります。条件式全体も偽になるため、警告は表示されません。

図2:&&による範囲内と||による範囲外

この図から分かること

0から100までの範囲内では、0以上と100以下の両方を満たす必要があります。そのため、&&を使います。

範囲外では、0未満または100より大きいのどちらか一方に該当すればよいため、||を使います。

数直線では、&&は2つの条件が重なる中央部分、||は左右どちらかの範囲を表します。

範囲判定で&&と||を間違えない

範囲内を判定するときに、&&と||を間違えることがあります。

正しい条件は次のとおりです。

brightness >= 0 && brightness <= 100

次の条件では、||を使っているため、意図した範囲判定になりません。

brightness >= 0 || brightness <= 100

たとえば、brightnessが150の場合を考えます。

  • 150 >= 0は真
  • 150 <= 100は偽
  • 真 || 偽は真

150は有効範囲を超えていますが、全体は真になります。

brightnessが-20の場合は、次の結果です。

  • -20 >= 0は偽
  • -20 <= 100は真
  • 偽 || 真は真

-20も有効範囲外ですが、全体は真になります。

この条件では、どの整数を入力しても少なくとも一方が真になるため、範囲内の判定としては使えません。

範囲内は下限と上限の両方を満たす必要があるため、&&を使用します。

!は条件の真と偽を反転する

!は、条件式の結果を反転する論理演算子です。

範囲内の条件が次の式で表されているとします。

brightness >= 0 && brightness <= 100

この条件全体を丸括弧で囲み、先頭に!を付けると、範囲内ではないという意味になります。

!(brightness >= 0 && brightness <= 100)
brightness範囲内の条件!で反転した結果
-10
0
50
100
120

範囲内なら元の条件が真なので、!を付けると偽になります。

範囲外なら元の条件が偽なので、!を付けると真になります。

!で範囲外を判定する

範囲内の条件を否定して範囲外を判定するプログラム

ファイル名:8_3_3.c

#include <stdio.h>

int main(void)
{
    int brightness;

    printf("画面の明るさを入力してください(0~100)> ");
    scanf("%d", &brightness);

    /* 範囲内の条件を否定して範囲外を判定する */
    if (!(brightness >= 0 && brightness <= 100)) {
        printf("警告: 明るさが有効範囲の外です。\n");
    }

    return 0;
}
実行結果の例
画面の明るさを入力してください(0~100)> -10
警告: 明るさが有効範囲の外です。
!を使ったプログラムの詳しい解説

-10を入力した場合は、最初に丸括弧内の範囲内条件を評価します。

  • -10 >= 0は偽
  • -10 <= 100は真
  • 偽 && 真は偽

次に、!によって偽を反転します。

  • !偽は真

最終的な条件式は真になるため、警告が表示されます。

次の2つの条件式は、どちらも0から100の範囲外を表します。

条件式考え方
brightness < 0 || brightness > 100外側の条件を直接書く
!(brightness >= 0 && brightness <= 100)範囲内の条件を否定する

どちらを使っても同じ範囲を判定できます。コードを読む人が理解しやすい書き方を選ぶことが大切です。

!を使うときは否定する範囲を丸括弧で明確にする

!がどの条件を否定しているのか分かるように、複数の条件を否定するときは丸括弧で囲みます。

!(brightness >= 0 && brightness <= 100)

この記述では、brightness >= 0 && brightness <= 100という条件全体を否定しています。

丸括弧がないと、!がどこまで影響するのか読み取りにくくなります。条件が長くなるほど、丸括弧でまとまりを明確にすることが大切です。

実践問題:指定した数で割り切れないか判定する

整数を5で割り切れるかどうかは、剰余演算子%を使って判定できます。

5で割った余りが0なら、5の倍数です。余りが0ではない場合は、5の倍数ではありません。

5の倍数ではない場合だけメッセージを表示するプログラム

ファイル名:8_3_4.c

#include <stdio.h>

int main(void)
{
    int number;

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

    /* 5で割った余りが0でなければ5の倍数ではない */
    if (number % 5 != 0) {
        printf("5の倍数ではありません。\n");
    }

    return 0;
}
実行結果の例

14を入力した場合は、5で割った余りが4なのでメッセージが表示されます。

整数を入力してください > 14
5の倍数ではありません。

15を入力した場合は、余りが0なので何も表示されません。

整数を入力してください > 15
倍数判定のプログラムを詳しく確認する

number % 5は、numberを5で割った余りを求めます。

numbernumber % 5number % 5 != 0動作
144メッセージを表示する
150何も表示しない
200何も表示しない
222メッセージを表示する

!=は、左右の値が等しくないかを判定する等価演算子です。

余りが0と等しくない場合は条件が真になり、5の倍数ではないと表示します。

実践問題:入力値が指定範囲にあるか判定する

次は、デジタルサイネージのリフレッシュレートが30Hz以上240Hz以下かを判定します。

範囲内になるには、次の両方を満たす必要があります。

  • refresh_rateが30以上
  • refresh_rateが240以下

両方を満たす必要があるため、&&を使用します。

リフレッシュレートが30Hzから240Hzの範囲内か判定するプログラム

ファイル名:8_3_5.c

#include <stdio.h>

int main(void)
{
    int refresh_rate;

    printf("リフレッシュレートを入力してください(Hz)> ");
    scanf("%d", &refresh_rate);

    /* 30Hz以上かつ240Hz以下なら有効な範囲 */
    if (refresh_rate >= 30 && refresh_rate <= 240) {
        printf("入力されたリフレッシュレートは有効です。\n");
    }

    return 0;
}
実行結果の例

144を入力した場合は範囲内です。

リフレッシュレートを入力してください(Hz)> 144
入力されたリフレッシュレートは有効です。

20を入力した場合は範囲外なので、メッセージは表示されません。

リフレッシュレートを入力してください(Hz)> 20
リフレッシュレートの範囲判定を詳しく確認する

144を入力した場合は、2つの条件が両方とも真になります。

  • 144 >= 30は真
  • 144 <= 240は真
  • 真 && 真は真

20を入力した場合は、下限の条件を満たしません。

  • 20 >= 30は偽
  • 20 <= 240は真
  • 偽 && 真は偽

境界値の30と240は有効範囲に含まれます。

refresh_rate30以上240以下全体の判定
29
30
144
240
241

チャレンジ問題:3つの長さで三角形を作れるか判定する

3つの整数を三角形の辺の長さとして使用するには、複数の条件をすべて満たす必要があります。

最初に、3つの値がすべて正の値であることを確認します。

  • a > 0
  • b > 0
  • c > 0

さらに、任意の2辺の和が残りの1辺より大きい必要があります。

  • a + b > c
  • a + c > b
  • b + c > a

どれか1つでも条件を満たさない場合は、三角形を作れません。そのため、すべての条件を&&でつなぎます。

図3:三角形を作るための複数条件

この図から分かること

三角形を作るには、3辺がすべて正の値であり、任意の2辺の和が残りの1辺より大きい必要があります。

5、6、8では、すべての条件が真になるため三角形を作れます。

2、3、5では、2 + 3 > 5が偽です。2 + 3は5と等しく、5より大きくないため、三角形を作れません。

三角形の判定では、1つでも条件が偽になると成立しないため、すべての条件を&&で組み合わせます。

3つの長さから三角形を作れるか判定するプログラム

ファイル名:8_3_6.c

#include <stdio.h>

int main(void)
{
    int a;
    int b;
    int c;

    printf("3つの辺の長さを入力してください > ");
    scanf("%d %d %d", &a, &b, &c);

    /* 正の値と三角形の成立条件をすべて確認する */
    if (a > 0 && b > 0 && c > 0 &&
        a + b > c && a + c > b && b + c > a) {
        printf("この3辺で三角形を作れます。\n");
    }

    return 0;
}
実行結果の例

5、6、8を入力した場合は、すべての条件を満たします。

3つの辺の長さを入力してください > 5 6 8
この3辺で三角形を作れます。

2、3、5を入力した場合は、成立条件を満たさないため、メッセージは表示されません。

3つの辺の長さを入力してください > 2 3 5
三角形の判定プログラムを詳しく確認する

条件式は、正の値を確認する部分と、辺の長さを確認する部分に分けられます。

条件確認する内容
a > 0aが正の値
b > 0bが正の値
c > 0cが正の値
a + b > caとbの和がcより大きい
a + c > baとcの和がbより大きい
b + c > abとcの和がaより大きい

5、6、8を入力した場合は、次のようになります。

  • 5、6、8はすべて正の値
  • 5 + 6は11なので8より大きい
  • 5 + 8は13なので6より大きい
  • 6 + 8は14なので5より大きい

すべての条件が真なので、&&で組み合わせた条件式全体も真になります。

2、3、5を入力した場合は、2 + 3が5と等しくなります。条件は2 + 3 > 5なので、この部分が偽です。

&&でつないだ条件は、1つでも偽があれば全体が偽になります。そのため、三角形を作れるというメッセージは表示されません。