c c 的位操作

2021-04-13 08:10:38 字數 2996 閱讀 6821

c/c++的位操作

《說明,本文章面向初學者,高手勿看,如有問題需要** 請發郵件: [email protected]

c/c++是一種系統程式語言,之所以這樣說其中乙個原因是是因為其提供的位操作的能力。其提供的位操作符直接對應於相關的彙編指令。在現實的程式設計實踐中,合理的使用位操作會大大提高效率。我先以乙個例子來開始我們的講解:

求乙個整數的絕對值

乍一看這個問題,我們一位這樣的問題太簡單了,所以你可能隨手會寫出這樣的程式:

inline int abs(int a)

^_^,或許此時你正在為你的傑作而沾沾自喜,呵呵這麼短小的函式,同時使用了inline,內聯之後減少函式呼叫的開銷,厲害啊,我怎麼就這麼有才呢?

先別急,我們來看一下這個程式有什麼問題:我們知道,現代的cpu都是嚴重依賴流水線的,不然的話他們的頻率怎麼會做的老高(ibm已經到4.6g了)。intel,amd的86的cpu的流水已經到十幾二十級了。所以這個時候,你一旦卡斷流水,那損失是相當大的。這個時候你會發現問題的所在了,原來你的程式卡斷了流水!!

這個時候你著急了,難道還有不用判斷的絕對值函式?有!首先我們來分析整數的表數方式:現代的計算機中,大多數是補碼表示的,負數呢就是原碼變反加1,正數就是原碼!如下:

-1:   00000000 00000000 00000000 00000001

---> 11111111 11111111 11111111 11111110 + 1

= 11111111 11111111 11111111 11111111

所以:設x、y為32位有符號整數,其中y=x>>31,則可以使用表示式(x^y)-y計算x的絕對值。由於x>>31是帶符號的向右位移,因此,x為負時,y為全1,即y等於-1;x非負時,y為全0,即y等於0。若非負,則x^y等於x,從而(x^y)-y等於x本身;若x為負,則x^y等於x按位取反,而減y等於加一,從而(x^y)-y等於x的絕對值。

inline int abs(int a)

(一).位運算子 & | ^ ~ << >>

這幾個運算子,相信已經很熟悉了,單數使用的時候未必真的用的很好。下面是乙個例子,你看看答案是多少?

int i= 1;

i = i<<1+2;

std::coutbit->bit31 = 1;

cout<

bitset<32>a;

bitset<32>b(2399);

bitset<32>c(string("1001"));

bitset<32>d(string("10011111"),4,3);

這三個例子說明了三種構造情況,呵呵看看中怎麼描述的:

bitset<32>a;          a有32位,每位都為0

bitset<32>b(2399)=》bitsetb(u);   b是unsigned long型u的乙個副本,當用unsigned long值作為bitset物件的初始值時,該值將轉化為二進位制的位模式。而bitset物件中的位集作為這種位模式的副本。如果bitset型別長度大於unsigned long值的二進位制位數,則其餘的高階位置為0;如果bitet型別長度小於unsigned long值的二進位制位數,則只使用unsigned值中的低階位,超過bitet型別長度的高階位將被丟棄

bitset<32>c(string("1001")); bitsetb(s);  b是string物件s中含有的位串的副本

當用string物件初始化bitset物件時,string物件直接表示為位模式。從string物件讀入位集的順序是從右向左,string物件和bitset物件之間是反向轉化的:string物件的最右邊字元(即下標最大的那個字元)用來初始化bitset物件的低階位(即下標為0的位)。當用string物件初始化bitset物件時,記住這一差別很重要。

bitset<32>d(string("10011111"),4,3);   bitsetb(s, pos, n)    b是s中從位置pos開始的n個位的副本

(2 )操作:

b.any()

b中是否存在置為1的二進位制位?

b.none()

b中不存在置為1的二進位制位嗎?

b.count()

b中置為1的二進位制位的個數

b.size()

b中二進位制位的個數

b[pos]

訪問b中在pos處的二進位制位

b.test(pos)

b中在pos處的二進位制位是否為1?

b.set()

把b中所有二進位制位都置為1

b.set(pos)

把b中在pos處的二進位制位置為1

b.reset()

把b中所有二進位制位都置為0

b.reset(pos)

把b中在pos處的二進位制位置為0

b.flip()

把b中所有二進位制位逐位取反

b.flip(pos)

把b中在pos處的二進位制位取反

b.to_ulong()

用b中同樣的二進位制位返回乙個unsigned long值

os << b

把b中的位集輸出到os流

這麼多的操作,看花眼了,不用著急,給你個程式,ctrl c  crtl v到你的編譯器中仔細看:

#include

#include

#include

using namespace std;

int main(int argc, char* argv)

(四)關於vector

所有關於位操作的書籍都會提及這個標準庫中的另類。呵呵如果你還不知道的話,建議你好好看看相關書籍,下面是幾個比較好的**:

如上所言,vector不是真正的stl容器,所以很多的操作跟vector並不相容,所以使用vector要小心。

(五)還有什麼容器適合於位操作呢?

boost::dynamic_bitset

大名頂頂的boost庫,不過這個還不是標準。

(寫完之後,覺得有點背離初衷,呵呵,還請各位原諒)

C C 位操作 位運算

在c語言中,可以單獨操控變數的位 bit 一般高階語言不會處理這級別的細節,c在提供高階語言便利的同時,還能為組合語言所保留的級別上工作,這使其成為編寫裝置驅動程式和嵌入式 的首選語言。目錄 二進位制整數 binary 有符號整數 八進位制 octal 十六進製制 hex 位運算子 按位與 的用途 ...

c c 中的位操作

c c 支援比較低階的位運算,在是眾人皆知的了。每本c c 的教科書都會說到這部分的內容,不過都很簡略,我想會有很多人不知道位運算用在什麼地方。這個帖子就簡略說說位運算的用處,更進一步的用法要大家自己去體會。而主要說的是操作標誌值方面。define bti msk bit 1 bit define ...

C C 中的位操作

1 位邏輯非運算 位邏輯非運算是單目的,只有乙個運算物件。位邏輯非運算按位對運算物件的值進行非運算,即 如果某一位等於0,就將其轉變為1 如果某一位等於1,就將其轉變為0。比如,對二進位制的10010001進行位邏輯非運算,結果等於01101110,用十進位制表示就是 145等於110 對二進位制的...