条件式を作るために必要な2種類の演算子とは…?
条件によってプログラムの動作を変えたいんだけど…
前回の記事でC言語の数値計算ができるようになりました!

きっと、計算するプログラムを作っていくうちに「計算結果でプログラムの動作を変えたい」と思われたのではないでしょうか…?
計算するプログラムを作れるようになったら、次は『条件分岐』を学んでいきましょう。
条件分岐とは『条件によってプログラムの動作を変える方法』のことです。
条件分岐を使えば、プログラムにたくさんの機能を追加することができるようになります。
それでは、さっそく条件分岐のやり方をご紹介いたします!
と言いたいところなのですが…
条件分岐を学ぶ前に『知っておかなければいけないこと』があるんです。
気になるところへGO!
C言語の条件分岐で使う条件式とは…?

条件によってプログラムの動作を変えるためには、『条件式』が必要です。
ここで言う条件式とは『動作を切り替えるときの条件を書いたコード』のことで、次のような書き方をします。
- 条件A
- 条件1 論理演算子 条件2
条件が1つの時は①のようにそのまま条件を書けばOKです。
条件が2つの時は、条件1と条件2の間に論理演算子というものを書く必要があります。
このような条件式を書けば、『条件1と条件2を同時に満たす』などのような複雑な条件を表現することができるのです。
このような条件式を作れるようになれば、自分が思った通りにプログラムの動作を変えられるようになります。
条件式を作るためには、次の2つの演算子をマスターすればOKです。
- 関係演算子
- 論理演算子
まず1つめの『関係演算子』ですが、これは条件に当てはまるかどうかを確認するために欠かせない行動を行う演算子になります。
条件を満たしているかを判断するためには『比較』が必要です。
というのも、『条件』と『今の状態』を比較しない限り、条件を満たしているかどうかを判断できないからです。
この比較を行うのが1つ目の『関係演算子』になります。
次は2つ目の論理演算子についてです。
先ほど少し触れましたが、論理演算子は2個以上の条件を組み合わせるときに使う演算子になります。
条件を作るために必要なC言語の『関係演算子』

まずは条件を作るために必要な関係演算子を一緒に学んでいきましょう。
C言語で準備されている関係演算子は次のとおりです。

これらの関係演算子は、左辺Aと右辺Bで挟むことで、AとBを比較することができます。
たとえば、『a==1』というような条件であれば、『変数aが1』のときに条件を満たすことになるんです。
このように、比較演算子は左辺と右辺のデータを比較して、条件に当てはまっているかをチェックします。
そして、条件を満たす場合は『1』を、条件を満たさない場合は『0』を出力するんです。
後日ご紹介する条件分岐の基本的なやり方は『条件式の結果が1になったときに動作を変更する方法』になります。
そのため、条件に当てはまったときに『1』を出力してくれる関係演算子が重要になるのです。
また、関係演算子は次の2種類に分類することができます。
- 等価演算子
- 比較演算子
一致・不一致を判断する『等価演算子』
最初にご紹介するのは、等価演算子です。
等値演算子には『==』『!=』の2種類があります。
『等価』という言葉があるように、この2つの等価演算子は左辺と右辺のデータの『一致・不一致』を確認する演算子なのです。
それでは、さっそくプログラムで動作を確認してみましょう。
#include<stdio.h>
int main(void) {
int i = 2;
printf("①一致OK:%d\n", i == 2); //成立
printf("②一致NG:%d\n", i == 1); //不成立
printf("③不一致OK:%d\n", i != 1); //成立
printf("④不一致NG:%d\n", i != 2); //不成立
return 0;
}
大方予想がついていると思いますが『==』は一致を、『!=』は不一致を判定します。
では、まず『==』を使った①と②のコードを見ていきましょう。
iには2が代入されているので、左辺と右辺が同じ値になるのは①ですよね。
なので、条件を満たした①は『1』が出力され、同じ値にならなかった②は『0』が出力されるのです。
『!=』が使われている③と④では、『左辺と右辺が同じ値ではない』ときに『1』を出力します。
そのため、不一致が成立している③では『1』を、不一致が成立していない(一致)④は『0』が出力されるのです。
等価演算子は『一致』『不一致』というピンポイントな条件を確認してくれる演算子です。
そのため、『対象を限定するとき』によく使われます。
『キャンペーン対象は30歳(age)だけ』という条件であれば『age==30』になりますし、
『男性は対象外』という条件であれば『gender==”女性”』や『gender!=”男性”』というような表現ができるのです。
範囲を指定する『比較演算子』
続いては比較演算子のご紹介です。
比較演算子は不等号を使った関係演算子のことで、意味は算数と同じになります。
左辺と右辺のデータを比較して、大小関係が成立する場合に『1』を出力するのです。
それでは、さっそくプログラムで動作を確認してみましょう。
#include<stdio.h>
int main(void) {
int i = 5;
printf("①=%d\n", i < 10); //成立
printf("②=%d\n", i > 5); //不成立
printf("③=%d\n", i <= 5); //成立
printf("④=%d\n", i >= 4); //成立
return 0;
}
まず①ですが、左辺のiには5が代入されていますので、右辺の10より小さいことが分かります。
よって、式が成立することになるので『1』が出力されるのです。
②は不等号が逆向きになったケースです。
今回は不等号に『=』がついていないので、5より小さい整数でなければ成立しません。
つまり、4以下の整数でなければ、『0』が出力されるんです。
③④は①②に『=』がついたものです。
不等号に『=』が付くと、左辺と右辺が一致する場合でも式が成立することになります。
④が成立することは一目瞭然ですが、③も左辺と右辺が同じ値になるので、成立することになるのです。
複数の条件を組み合わせる『論理演算子』

冒頭でご紹介したように、1つの条件だけでも条件式として使うことはできます。
でも、複数の条件を満たしたときだけ実行したい処理もありますよね?
複数の条件を組み合わせたいときは、次の論理演算子を使います。

『&&』と『||』の使い方は関係演算子と一緒ですが、『!』だけ使い方が違うので注意が必要です。
#include<stdio.h>
int main(void) {
int i = 5;
printf("①=%d\n", (3 <= i) && (i <= 10)); //成立
printf("②=%d\n", (6 <= i) && (i <= 9)); //不成立
printf("③=%d\n", (i <= -20) || (0 <= i)); //成立
printf("④=%d\n", (i <= -20) || (20 <= i)); //不成立
printf("⑤=%d\n", !(i == 10)); //不成立を逆転
printf("⑥=%d\n", !(i == 5)); //成立を逆転
return 0;
}
まずは『&&』を使っている①と②をみていきましょう。
『&&』は左と右の条件を同時に満たすときだけ『1』を出力する演算子です。
①の場合、左の条件は『3以上の数値』、右の条件は『10以下の数値』ということが読み取れます。
つまり、同時に条件を満たすためにはiは『3~10』の数値であることが必須条件なのです。
②も同じように条件を組み合わせて考えると、条件を満たすためには『6~9』の数値である必要があります。
今回のプログラムの場合はi=5なので、条件を満たしている①は『1』を、満たしていない②は『0』を出力しているのです。
続いては『||』を使用している③④のコードです。
『||』は左と右の条件のどちらか1つでも満たしていれば『1』を出力する演算子になります。
③のコードでは、右側の条件である『0以上』を満たしているため『1』が出力されています。
④では、どちらの条件にも当てはまらないので、『0』が出力されているのです。
最後は⑤⑥の否定を意味する演算子『!』です。
条件を否定することになるので、条件が出力した値を反転することができます。
イメージとしては『0→1』に、『1→0』に変換することができるのです。
先ほどのプログラムの⑤の場合、『i==10』が成立しないことは一目瞭然です。
『!』はこの結果を否定することになるので、『i==10』が出力した『0』を逆転させて『1』になっています。
⑥のコードはこの逆で、成立した『i==5』が出力した『1』を逆転させて『0』になっているのです。

条件式で注意が必要な短絡演算

条件式を作る際の注意点は『重要な条件は左側の条件1に書く必要がある』ということです。
実は論理演算子を使って条件を組み合わせると、エラーが起きることがあります。
例えば『i=0、j=10』の時に『(i>5) && (j>5)』という条件式を作ったら、どのような動作をすると思いますか…?
プログラムは先頭から順番に読み込まれていくため、左側の条件が先に読み込まれてチェックされることになります。
そして、そのあとに右の条件をチェックするのですが…
左の条件を確認した時点で条件式が成立しないことが分かった場合は、右の条件はチェックされないのです。(この現象を『短絡演算』と言います。)
先ほどの例の『(i>5) && (j>5)』という条件式であれば、どちらの条件から確認しても問題はありません。
ですが、もし『iが存在するならi>10をチェックする』という条件ならどうでしょうか…?
ご想像の通り、変数が存在しない可能性がある場合は、『変数が存在すること』を先にチェックしなければいけません。
C言語で存在しない変数を使おうとすると、思わぬ動作をすることがあるからです。
このような異常を防ぐためには、重要な条件を先にチェックする必要があります。
そのためには、重要な条件は左側に書いて先にチェックする必要があるのです。
論理演算子『!』の注意点

もしかしたら、先ほどのプログラム例の⑤をみて、『!(i == 10)』は『i != 10』と同じ意味になる事に気づかれたかもしれませんね。
お察しの通り、否定の論理演算子『!』は別の表現で書き換えることもできます。
では、実際の開発ではどちらの演算子を使えばいいのでしょうか…?
実際の開発などでは『!』を使うことは最小限にしましょう!
というのも、『!』を使うとケアレスミスが発生する可能性が高いからです。
『!』をつかうと、否定する前の条件を頭の中で考える必要がある上に、『!』を見落とす危険性もあるからです。
実際に次のどちらの条件が分かりやすいか、確認してみてください。
① (number<=5) && (number>=10)
② !((number>5) && (number<10))
①の条件の方が圧倒的に分かりやすかったと思います。
というのも、①はコードを読むだけで条件を理解できるからです。
一方、『!』を使った②では『5より大きくて10より小さい』という条件を先に考えてから逆の条件を考える必要があります。
頭の中で条件を考えてから否定する必要があるので、理解しづらくなるんですよ。
まとめ
以上が条件分岐を使う前に知っておきたい『条件式の作り方』になります。
関係演算子と論理演算子を使いこなして条件式を作れるようになれば、条件分岐も簡単に使えるようになりますよ。
