C 速查手冊

位元運算

資料 (data) 儲存在電腦中的方式為利用 01 的編碼,例如八位元的整數 25

0001 1001

另如 ASCII 編碼中的字母 f

0110 0110

所謂的位元運算,就是逐位元 (bit) 進行比較,例如以上兩項編碼做邏輯或的位元運算

   0001 1001
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
$

這裡我們整數採用十六進位的表示方法,同時在十六進位中每一位元只用 01 兩種數字,因此可看成如同只有 01 的二進位一般。由此 ab ,由於只有最右邊的位元相同,所以結果為 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 變成 11 變成 0 ,簡單說就是原數字與補數相加會等於全部的位元皆為 1 ,所以就十六進位來講,會是全部的位數都為 f

回 C 速查手冊首頁