ビット演算子
C言語のビット演算子について解説します。ビット演算とは、1ビット単位で行われる演算のことをいいます。
| ビットAND演算子 | & |
|---|---|
| ビットOR演算子 | | |
| ビットXOR演算子 | ^ |
| ビットNOT演算子 | ~ |
ビットAND演算子
ビットAND演算子「&」は、二つのオペランドに含まれるあるビットが両方とも1の場合に、返却する値の対応する位置に1に設定し、あるビットのどちらかが0の場合は0を設定します。
# ビットAND x & y
xとyが両方とも8bit符号なし整数型であるとしましょう。zがビットAND演算子の結果の値です。xとyのある位置の両方のビットが1の場合に、対応するzのビットも1になり、それ以外の場合は0になります。
x 01001100 y 01000101 z 01000100
ビットAND演算子のサンプルです。
#include <stdio.h>
#include <stdint.h>
int main(void) {
// 01001100
uint8_t x = 0x4C;
// 01000101
uint8_t y = 0x45;
// 01000100
uint8_t z = x & y;
printf("%X\n", z);
}
出力結果です。16進数での出力ですが、2進数であれば「01000100」です。
44
ビットOR演算子
ビットOR演算子「|」は、二つのオペランドに含まれるあるビットのどちらかが1(どちらも1でもよい)の場合に、返却する値の対応する位置に1に設定し、あるビットの両方が0の場合は0を設定します。
# ビットOR x | y
xとyが両方とも8bit符号なし整数型であるとしましょう。zがビットOR演算子の結果の値です。xとyのある位置のどちらかのビットが1の場合に、対応するzのビットも1になり、両方とも0の場合は0になります。
x 01001100 y 01000101 z 01001101
ビットOR演算子のサンプルです。
#include <stdio.h>
#include <stdint.h>
int main(void) {
// 01001100
uint8_t x = 0x4C;
// 01000101
uint8_t y = 0x45;
// 01001101
uint8_t z = x | y;
printf("%X\n", z);
}
出力結果です。16進数での出力ですが、2進数であれば「01001101」です。
4D
ビットXOR演算子
ビットXOR演算子「^」は、二つのオペランドに含まれるあるビットがのどちらかだけが1の場合に、返却する値の対応する位置に1に設定し、あるビットの両方が0あるいは1の場合は0を設定します。
# ビットXOR x ^ y
xとyが両方とも8bit符号なし整数型であるとしましょう。zがビットXOR演算子の結果の値です。xとyのある位置のどちらかだけのビットが1の場合に、対応するzのビットも1になり、両方とも0または1の場合は0になります。
x 01001100 y 01000101 z 00001001
ビットXOR演算子のサンプルです。
#include <stdio.h>
#include <stdint.h>
int main(void) {
// 01001100
uint8_t x = 0x4C;
// 01000101
uint8_t y = 0x45;
// 0001001
uint8_t z = x ^ y;
printf("%X\n", z);
}
出力結果です。16進数での出力ですが、2進数であれば「0001001」です。
9
ビットNOT演算子
ビットNOT演算子「~」は、オペランドに含まれるあるビットを反転させます。
# ビットNOT ~x
xとyが両方とも8bit符号なし整数型であるとしましょう。zがビットNOT演算子の結果の値です。xのビットが反転しています。
x 01001100 z 10110011
ビットNOT演算子のサンプルです。出力結果は、整数型拡張の影響をなくすために「0xFF」とのビットANDをとっています。
#include <stdio.h>
#include <stdint.h>
int main(void) {
// 01001100
uint8_t x = 0x4C;
// 01000101
uint8_t y = 0x45;
// 10110011
uint8_t z = ~x;
printf("%X\n", z);
}
出力結果です。16進数での出力で、すが、2進数であれば「01000100」です。
B3
ビット演算子と「=」を組み合わせた特殊演算子
ビット演算子と「=」を組み合わせた特殊演算子があります。
# 「x = x & y」 と同じ意味 x &= y # 「x = x | y」 と同じ意味 x |= y # 「x = x ^ y」 と同じ意味 x ^= y
ビット演算子は実務ではどのような場合に使用しますか?
ビット演算子を一番使う場面は、フラグを関数の引数に渡す場合です。C言語では、フラグを、整数で渡すことが多いのですが、その場合に、ビットの位置で意味を定めます。列挙型enumを使って、各ビットのフラグを定義します。1(二進で1), 2(二進で10), 4(二進で100), 8(二進で1000)。
各ビットを立てるときはビットOR「|=」、落とすときはビットXOR「^=」です。
ビットが立っているかをチェックするときは「&」を使います。
関数の引数に渡すフラグを作成するサンプルコードです。
#include <stdio.h>
#include <stdint.h>
enum {
MYAPP_FLAG1 = 1,
MYAPP_FLAG2 = 2,
MYAPP_FLAG3 = 4,
MYAPP_FLAG4 = 8,
MYAPP_FLAG5 = 16,
MYAPP_FLAG6 = 32,
MYAPP_FLAG7 = 64,
MYAPP_FLAG8 = 128,
MYAPP_FLAG9 = 256,
MYAPP_FLAG10 = 512,
};
int main(void) {
uint32_t flag = 0;
// MYAPP_FLAG4をたてる
flag |= MYAPP_FLAG4;
// 00000000 00000000 00000000 00001000
printf("%X\n", flag);
// MYAPP_FLAG10をたてる
flag |= MYAPP_FLAG10;
// 00000000 00000000 00000010 00001000
printf("%X\n", flag);
// MyAPP_FLAG4を落とす
flag ^= MYAPP_FLAG4;
// 00000000 00000000 00000010 00000000
printf("%X\n", flag);
// ビットが立っているかチェック
if (flag & MYAPP_FLAG10) {
printf("MYAPP_FLAG10 ok\n");
}
}
C言語ゼミ


