本文へスキップ
BecomeCoder

C言語コース · 第12章 ビット操作 · レッスン46

ビット演算子 ― &, |, ^, ~, <<, >>

ブラウザで完結

導入

ゲームの状態管理や通信のヘッダなど、「1つの整数の中に複数のON/OFFスイッチを詰め込みたい」場面があります。そのために使うのが、整数を2進数のビット単位で操作するビット演算子です。

説明

intunsigned int はコンピュータの中では2進数(0と1の並び)として表現されています。例えば 12 は2進数で 1100101010 です。ビット演算子は、この0/1の並びを1桁(1ビット)ずつ操作します。

  • &(AND) … 両方のビットが1のときだけ1になる。
  • |(OR) … どちらかのビットが1なら1になる。
  • ^(XOR、排他的論理和) … 2つのビットが異なるときだけ1になる。
  • ~(NOT、単項演算子) … すべてのビットを反転する(0↔1)。
  • <<(左シフト) … ビットを左にずらす。1回ずらすごとに値は2倍になる。
  • >>(右シフト) … ビットを右にずらす。1回ずらすごとに値は半分(整数の割り算と同じ切り捨て)になる。
flowchart LR
  a["a = 1100 (12)"] --- op["& (AND)"]
  b["b = 1010 (10)"] --- op
  op --> r["結果 = 1000 (8)"]
#include <stdio.h>

int main(void) {
    unsigned int a = 12;   // 2進数: 1100
    unsigned int b = 10;   // 2進数: 1010

    printf("a & b = %u\n", a & b);              // 1000 = 8
    printf("a | b = %u\n", a | b);               // 1110 = 14
    printf("a ^ b = %u\n", a ^ b);               // 0110 = 6
    printf("~a の下位8bit = %u\n", (~a) & 0xFF);  // 11110011 = 243
    printf("a << 2 = %u\n", a << 2);              // 110000 = 48
    printf("a >> 2 = %u\n", a >> 2);              // 0011 = 3

    return 0;
}

~aaすべてのビット(unsigned int なので通常32ビット分)を反転するので、そのまま表示すると非常に大きな数になります。上の例では & 0xFF で「下位8ビットだけ取り出す」マスク処理をしてから表示し、結果が分かりやすくなるようにしています。このように「他のビットに影響を与えず、注目したいビットだけを取り出す/変更する」ときに使う値をビットマスクと呼びます(次のレッスンで詳しく使います)。

やってみよう

ab の値を変えて結果がどう変わるか確認しましょう。a << 1a << 3 のようにシフトする回数を変えて、シフトが「2倍・4倍・8倍」に対応することを確かめてみてください。

演習

unsigned int x = 6;unsigned int y = 3; を使って、x & yx | yx ^ y の3つの結果をそれぞれ1行ずつ表示してください。

ヒント1を見る

printf("%u\n", x & y); のように3回 printf します。

ヒント2を見る

6は2進数で 0110、3は 0011 です。ANDは両方1のビットだけ残ります。

実際に動かしてみよう

下のエディタにCを書いて「実行」を押すと、ブラウザ内のインタプリタで出力が表示されます。本文の例をそのまま試したり、書き換えたりしてみましょう(scanf を使う回は「標準入力」欄に値を入れてから実行します)。

C/C++ — ブラウザ内で実行

ブラウザ内でC/C++を動かす学習用インタプリタ(JSCPP)を読み込みます(入門向けのサブセットです)。
スクロールして表示された時点でも自動で読み込まれます。