3週目:ビット演算子

算術演算子,関係演算子,論理演算子などについては,演習1で学習してきた.本課題では,さらに,ビット演算子について学習する.画像の各画素に,&(AND)演算などのビット演算を施すことにより,各演算子の動作を理解する.

作業課題

  1. 先週作成したプロジェクトex4_2の中の 画像処理モジュール img_proc.c に,サンプルプログラム3に記載されている関数 ipBitMask を書き加えなさい. (関数ipBitMaskは画像の各画素の下位”6”ビットを0でマスクする処理を行う関数である.)
  2. img_proc.hに関数ipBitMaskのプロトタイプ宣言を書き加えなさい.
  3. main.c 内で 関数ipRotateImage を呼び出している箇所を 関数ipBitMask を呼び出すように書き換え,プログラムを実行後,どのような画像が出力されるか確かめなさい.

演習課題

以下の仕様を満たすプログラムを作成せよ.
コマンドプロンプトでの実行方法の例

> Z:
> cd (各自のディレクトリ)\ex4_2\Debug
> ex4_2.exe 0 img01.ppm result3.ppm

解説

(1)ビット演算子

ビット演算が適用できるのは整数(char, short, int, long)に限られる.整数であれば,signed(符号付き)でもunsigned(符号なし)でも良いが,結果を格納する変数の型によって,符号付きか符号なしかで結果が異なる場合がある点に注意する.

C言語で用意されているビット演算子は以下の6つである.

演算子 名称
& ビットごとのAND演算子 
| ビットごとのOR演算子 
^ ビットごとの排他的OR演算子 (XOR)
対応するビットが異なるときには1,同じときには0がセットされる.
<< 左シフト
空になる下位ビットには0が入る.
>> 右シフト
符号なし数の場合,上位ビットには0が入る.
符号付き数の場合,上位ビットには符号桁が入る.
~ 1の補数演算子 (単項演算子)
ビットを反転する.

論理演算子の && や || とは違う点に注意する.

また,算術演算子(+,-,*,/)と同様に,複合代入演算の形(&=, |=, >>= など)も利用できる.

下の表に具体例を挙げる.ここで,変数A,B,C,Dの型と初期値は以下の通りとする.

unsigned char A = 113; (16進 0x71, 2進 0111 0001)
unsigned char B = 15; (16進 0x0F, 2進 0000 1111)
char C = -64; (16進 0xC0, 2進 1100 0000)
char D = 0;

結果 (カッコ内は16進表記と10表記)
D = A & B
A: 0111 0001
B: 0000 1111
D: 0000 0001 (0x01,1)
D = A | B
A: 0111 0001
B: 0000 1111
D: 0111 1111 (0x7F,127)
D = A ^ B
A: 0111 0001
B: 0000 1111
D: 0111 1110 (0x7E,126)
D = B << 2
B: 0000 1111
D: 0011 1100 (0x3C,60)
2ビット左シフトすると4倍になる
D = A >> 3
A: 0111 0001
D: 0000 1110 (0x0E,14)
3ビット右シフトすると8分の1になる
D = C >> 3
C: 1100 0000
D: 1111 1000 (0xF8,-8)
符号付き数である点に注意する
D = ~A
A: 0111 0001
D: 1000 1110 (0x8E,-114)
A >>= 2
複合代入演算の例
A: 0111 0001←式の実行前
A: 0001 1100←式の実行後

A = 3, B = 33, C = -2のとき,上記の式の結果はそれぞれどのようになるか求めよ.終わったらTAに採点してもらうこと.

演算子の優先順位と結合規則について,書籍やオンラインヘルプなどで確認し,よく理解しておくこと.

(2)プログラムの設計指針〜ビット演算と画像処理〜

説明用スライド (授業用) (印刷用)