C 速查手冊
3.5 位元運算子
資料 (data) 儲存在電腦中的方式為利用 0 與 1 的編碼,例如八位元的整數 25 為
0001 1001
另如 ASCII 編碼中的字母 f 為
0110 0110
所謂的位元運算,就是逐位元 (bit) 進行比較,例如以上兩項編碼做邏輯或的位元運算
0001 1001
or 0110 0110
or 0110 0110
結果會是
0111 1111
C 語言的位元運算子如下表
運算子 | 功能 | 範例 |
---|---|---|
& | 且 | a & b |
| | 或 | a | b |
^ | 互斥或 | a ^ b |
<< | 向左位移 | a << b |
>> | 向右位移 | a >> b |
~ | 取 1 的補數 | ~a |
以下例子示範位元運算子且、或、互斥或
#include <stdio.h>
int main(void)
{
int a = 0x101;
int b = 0x11;
printf("%x\n", a & b);
printf("%x\n", a | b);
printf("%x\n", a ^ b);
return 0;
}
/* 《程式語言教學誌》的範例程式
http://kaiching.org/
檔名:bitlogic.c
功能:示範位元運算子且、或、互斥或
作者:張凱慶 */
編譯後執行,結果如下
$ gcc bitlogic.c |
$ a.out |
1 |
111 |
110 |
$ |
這裡我們整數採用十六進位的表示方法,同時在十六進位中每一位元只用 0 跟 1 兩種數字,因此可看成如同只有 0 跟 1 的二進位一般。由此 a 且 b ,由於只有最右邊的位元相同,所以結果為 0x1 ,其餘可類推。
以下例子示範位元向左位移跟向右位移運算子
#include <stdio.h>
int main(void)
{
int a = 0x100;
int b = 0x4;
printf("%x\n", a << b);
printf("%x\n", a >> b);
return 0;
}
/* 《程式語言教學誌》的範例程式
http://kaiching.org/
檔名:bitshift.c
功能:示範位元運算子向左及向右位移
作者:張凱慶 */
編譯後執行,結果如下
$ gcc bitshift.c |
$ a.out |
1000 |
10 |
$ |
就整數型態而言,向左位移一個位元等於原數字乘上 2 ,向右位移一個位元等於原數字除以 2 ,所以向左位移 4 個位元等於原數字乘上 16 ,這對十六進位來講就等同向左進一位,向右位移 4 個位元可依此類推。
以下例子示範位元取 1 的補數運算子
#include <stdio.h>
int main(void)
{
int a = 0x0;
int b = 0x56789102;
int c = 0x100;
printf("%x\n", ~a);
printf("%x\n", ~b);
printf("%x\n", ~c);
return 0;
}
/* 《程式語言教學誌》的範例程式
http://kaiching.org/
檔名:bitnot.c
功能:示範位元取 1 的補數運算子
作者:張凱慶 */
編譯後執行,結果如下
$ gcc bitnot.c |
$ a.out |
ffffffff |
a9876efd |
ffffffff |
$ |
所謂取 1 的補數運算子就是把所有的 0 變成 1 , 1 變成 0 ,簡單說就是原數字與補數相加會等於全部的位元皆為 1 ,所以就十六進位來講,會是全部的位數都為 f 。