分岐文2
演算子
前回は比較演算子や関係演算子に関して取り上げましたが、今回はそれ以外の演算子について説明したいと思います。
◆論理演算子
論理演算子は論理演算を行うための演算子です。論理演算というのは真と偽を比較して、値を算出する演算です。
算出されるのは真であれば「1」に偽になるときは「0」となります。「||」や「&&」は左辺から評価されるため、
左辺で条件判定できてしまった場合、判定をそこで停止します。そのため右辺が実行されないケースもありえます。
論理演算子 | 使用例 | 説明 |
---|---|---|
! | !x | 否定となります。偽の時に真を返し、真の時に偽を返します |
|| | x > 0 || y > 0 | 左辺と右辺がどちらか一方が真であれば真となり、それ以外は偽を返します |
&& | x > 0 && y > 0 | 左辺と右辺が共に真であれば真となりそれ以外は偽となります |
コードで確認
ではコードで確認してみましょう。
#include <stdio.h> int main(void){ int a = 10; int b = 20; if(a == b || (b = 3) > 0 ){ printf("条件式1 真です a:%d b:%dn", a, b); } if(a == b && (b = 5) > 0 ){ printf("条件式2 真です a:%d b:%dn", a, b); }else{ printf("条件式2 偽です a:%d b:%dn", a, b); } if(!a){ printf("条件式3 真です a:%d b:%dn", a, b); }else{ printf("条件式3 偽です a:%d b:%dn", a, b); } return(0); }
~~~~実行結果~~~~
条件式1 真です a:10 b:3
条件式2 偽です a:10 b:3
条件式3 偽です a:10 b:3
~~~~~~~~~~~~
結果を見てみましょう。
最初のif文ですが、最初の「a==b」は関係演算子で等しいか同課の判定となります。
aとbの値を比較すると当然ながら偽となりますが、次のところでまず「(b=3)」が実行されてその数と0の大小を
比較して真となります。「||」はどちらかが真であれば真となるため、printf関数が実行されます。
このifではelseを使用しない構文を使用しています。
2番目のif文は最初のif文と同様に左辺が偽となります。「&&」は左辺と右辺が共に真でなければ、真とならないため
左辺が偽となっている時点で右辺の評価をする必要がありません。
そのため「(b = 5)」は実行されないため、bは「3」のままとなります。
3番目のif文はaが「10」なのでそのまま評価すれば真となりますが、「!」はその否定となるので逆の偽となります。
◆ビット演算子
ビット演算というのはビット単位の操作を行うときに使用される演算子となります。
ただしこのビット演算が使用できるのは整数だけとなります。
ビット演算子 | 使用例 | 説明 |
---|---|---|
& | a & 0xf0 | ビットごとのANDとなります。ANDとは両方のビットが1の時に1となります。 |
| | a & 0xf0 | ビットごとのORとなります。ORとはどちらかのビットが1の時に1となります。 |
^ | a ^ 0xf0 | ビットごとのXORとなります。XORとは両方のビットが異なっている時に1となります。 |
~ | ~a | ビットを反転させます。 |
<< | a << 3 | ビットの並びを左にシフトします。シフトすると2倍になります。 |
>> | a >> 3 | ビットの並びを右にシフトします。シフトとすると1/2になります。 |
それぞれの処理によりどういったことが行えるのか見てみましょう。
& AND
両方が1の時に1となりますので変数の中身が以下のようになっている場合に「&」を使用すると、
結果は下記のようになります。ビット列の取り出したい部分だけを抜き出す時などに使用されます。
下記の場合、変数aの上位4バイトが抜き出せます。
| OR
どちらかが1の時に1となりますので変数の中身が以下のようになっている場合に「|」を使用すると、
結果は赤枠のようになります。特定のビットを1にしたい場合などに使用されます。
^ XOR
ビットが異なる時に1となりますので変数の中身が以下のようになっている場合に「^」を使用すると、
結果は下記のようになります。ある部分のビットを反転させたいときに使用されます。
下記の場合、変数aの上位4バイトが反転します。
~ 補数
シフト演算
左シフト
シフト演算のときに気を付けなければならないこととして、符号付きと符号なしで処理が変わるものがあるところです。
まず左シフトから見ていきます。左シフトした場合、一番右の桁には「0」が入るようになっています。ずれて枠外にいった
部分は破棄されます。左に3シフトすると以下のようになります。
右シフト
右シフトの場合は、符号なしと符号ありで処理が変わります。符号なしの場合は、左に0が格納されますが、符号ありの場合
処理系により、算術シフト(符号ビットを追加していく)論理シフト(0を追加していく)の2通りに分かれます。
右に2シフトすると以下のようになります。
コードで確認
ではコードで確認してみましょう。
#include <stdio.h> int main(void){ unsigned ichar num1 = 1; unsigned char num2 = 2; printf("num1とnum2の論理和は%dn",num1 | num2); printf("num1とnum2の論理積は%dn",num1 & num2); printf("num1とnum2の排他的論理和は%dn",num1 ^ num2); printf("num1を反転させると%dn",~num1); printf("num1を左に2シフト%dn",num1 << 2); printf("num2を右に2シフト%dn",num2 >> 1); return(0); }
~~~~実行結果~~~~
num1とnum2の論理和は3
num1とnum2の論理積は0
num1とnum2の排他的論理和は3
num1を反転させると-2
num1を左に2シフト4
num2を右に2シフト1
~~~~~~~~~~~~
今回用意した変数num1とnum2には以下の値が格納されているので表示と照らし合わせて見てください。
実践力が身につくC言語講座 連載リンク
競技プログラミングをイメージしたライブラリ活用講座
競技プログラミング風-標準Cライブラリ入門 連載
アルゴリズムをマスターして技術力アップ!
実践アルゴリズム講座 連載
パズルゲームの解析をテーマにしたC++講座
ゲーム解析プログラミング 連載