在vc++程式設計中,會發現微軟的很多api裡面都用到了位運算,比如這個函式:
createwindowexa(__in dword dwexstyle,
__in_opt lpcstr lpclassname,
__in_opt lpcstr lpwindowname,
__in dword dwstyle,
__in
intx,
__in
inty,
__in
intnwidth,
__in
intnheight,
__in_opt hwnd hwndparent,
__in_opt hmenu hmenu,
__in_opt hinstance hinstance,
__in_opt lpvoid lpparam);
這是windows api裡面建立視窗的函式,第四個引數dwstyle,表示視窗風格,視窗風格當然會有很多種, 而且很多種之間也是可以組合的,那麼到底怎麼樣用乙個引數表示這麼多中風格以及這些風格之間的組合呢?注意到了在寫程式的時候這個引數經常是這樣的:
windows中dword為32位,我們仔細研究發現, 每種最基本的視窗風格如ws_borderz換換成二進位制為100000000000000000000000,發現其32位中只有一位為1, 對應其他風格也都類似只有一位為1。假如視窗風格有32種(當然沒那麼多),那麼dwstyle引數32位的每一位對應一種風格, 這一位為1就有這個風格, 為0 就沒這個風格,這樣我們就能通過位運算將不同的風格組合在一起或者去掉某種風格。在建立視窗的時候只需要解析出dwstyle對應的每一位是否為1我們就能知道是否要包含這種風格。說了這麼多來看看我的**吧:
//判斷dword對應位是否為1
//b為需要判斷的數, i為對應的位數
bool testdword(dword b, dword i)
//將某一位置為1或者0
//p為需要改變的數的指標,i為需要置0的位數
//state為0或者1,
//其也只能為0或1(二進位制每一位不是0就是1)
void setdwbit(dword* p, int
i, dword state)
上文中我的**因為是在atl下寫的所以用的atlassert,大家沒有使用atl的可以自己改掉。注意到函式中我都是用0x01移位操作的。testdword判斷某一位是否為1, setdwbit將對應的某一位置為0 或者1。有了這兩個函式我們就能很方便的在自己的**中使用位運算。比如我們可以用乙個dword(32位)型變數表示某個物件對應的是否有32個狀態,注意此處我的第二個引數是位數是對應0到31的所以需要0x01《很多時候我們都可以用乙個變數表示很多種狀態,而不需要為每種狀態定義乙個變數,這樣我們的程式會更簡潔更高效。以上函式用到位運算,如果不熟悉位運算的可以自己查資料。有什麼錯誤請大家指出。
位運算的妙用
位運算的操作 負數是按照補碼的形式參與按位與運算的 原碼就是符號位加上真值的絕對值,即用第一位表示符號,其餘位表示值.1為正,0為負 反碼的表示方法是 正數的反碼是其本身 負數的反碼是在其原碼的基礎上,符號位不變,其餘各個位取反.補碼的表示方法是 正數的補碼就是其本身 負數的補碼是在其原碼的基礎上,...
位運算的妙用
做題中常用的位運算有以下幾種 判斷奇偶性 if n 1 else 常用於快速冪和其他判斷奇偶性的地方 乘除2的整次冪 scanf d d n,m 輸出n乘2的m次方 printf d n m 線段樹求左兒子可以用 id 1得到,乙個偶數n 加1可以寫做n 1,如求左兒子可以用 id 1 1得到。sc...
位運算的妙用技巧
c c 語言提供的位運算子有 運算子含義功能 按位與兩個二進位制位都為 則該位的結果值為 否則為 按位或兩個二進位制位中只要有乙個為 該位的結果值為 按位異或兩個二進位制位不同則結果為 真 相同則結果為 假 取反乙個二進位制數按位取反,即將 變 將 變 左移左移運算子是用來將乙個數的各二進位制位全部...