按位運算符
基本位運算符:取反~, 與&, 或|, 異或^
- 按位取反: ~
unsigned char tmp = 2;
printf("%d", ~tmp);
2的二進制是:0000 0010
取反後:1111 1101 解釋成補碼為:(等價于原碼1000 0011 = -3)
- 按位與:&
隻有1 & 1 = 1, 其他都為0 , 即:全1為1,有0則0
- 按位或:|
隻有0 | 0 = 0, 其他都為1,即:全0為0,有1則1
- 按位異或: ^
相同為0, 相異為1
0 ^ 0 = 0,1 ^ 1 = 0
0 ^ 1 = 1, 1 ^ 0 = 1
基本運算符的應用
-
&
的應用:掩碼MASK
不論是0還是1,和0進行與運算為0,和1進行與運算不變:
是以
上MASK後,0對應的位被消去,隻有1對應的位保留:類似于用0掩蓋住原二進制串上對應的位:結果是隻有1對應的位被保留,其餘的位為0;與
- 可簡寫為:
-
檢查位
目的:檢查MASK中1對應位是否為1
先用掩碼(與上MASK),得到第一次處理後的二進制串(其餘不相幹的位置為0),然後==判斷是否與MASK相等:若相等說明MASK中1對應的位也都是1,否則有的位檢查失敗
-
關閉位(清空位)
類似于掩碼:用&将0對應位清空(置為0),一般先将MASK取反,MASK中1的位就是要關閉的位
-
的應用:打開位(設定位)|
無論0還是1,和1進行或運算為1:
是以
或
上MASK後,可将特定位置為1(ON),用于對特定硬體發送打開指令
-
^
的應用:切換位
無論0還是1,與0異或不變,與1異或“翻轉”:
是以
上MASK後,可将MASK中1對應的位翻轉異或
移位運算符: 右移 >>, 左移 <<
- 左移
: 低位補0<<
- 右移
:無符号數補0,有符号數看機器>>
移位運算符的應用:
a << n; // 左移一位相當于*2: 左移n位相當于*2^n
a >> n; // 如果a非負,右移一位相當于/2:右移n位相當于/2^n
可以利用移位+掩碼:來提取某個或某些位
應用:ItoB(),invert_end()
獲得int 的二進制:并實作将低n位翻轉的函數
#include <stdio.h>
#include <limits.h> //提供CHAR_BIT:本機一個位元組的位數(通常為8)
#define MASK 0x01
void ItoB(int, char*);
void ShowBit(char*);
int invert_end(int, int);
int main(){
char ans[CHAR_BIT * sizeof(int) + 1];
int in;
puts("Enter integers and see them in binary.(Non-numeric to quit)");
while(scanf("%d", &in) == 1){
ItoB(in, ans);
printf("%d in binary is ", in);
ShowBit(ans);
putchar('\n');
puts("Inverting the last 4 bits.");
ItoB(invert_end(in, 4), ans);
ShowBit(ans);
putchar('\n');
}
return 0;
}
void ItoB(int n, char* s){
int i;
const static int size = CHAR_BIT * sizeof(int);
for(i = size - 1; i >= 0; --i, n >>= 1){
s[i] = (n & MASK) + '0';
}
s[size] = '\0';
return s;
}
void ShowBit(char* s){
int i = 0;
while(s[i]){
putchar(s[i]);
if(++i % 4 == 0 && s[i]){
putchar(' ');
}
}
}
int invert_end(int n, int bits){
int mask = 0;
int bitval = 1;
while(bits-- > 0){
mask |= bitval;
bitval <<= 1;
}
return n ^ mask;
}
- 輸出:
- 實作翻轉低位功能後: