C語言位操作

2021-07-11 11:51:57 字數 3145 閱讀 3706

<< 左移      右端補零,操作的物件是 任意 int char   這裡任意是指有無符號的意思。

>> 右移      無符號數或者是正數不用考慮是左端補0, 負數看實現【一些實現補0,一些保留符號位,這種比較科學吧】

~   按位取反   【一元運算子】

&   按位與

^   按位異或

|    按位或

為了保證可移植性,暫存器當然用unsinged char 或者unsinged int ,當然更詳細一點的posix標準裡的

1位元組     uint8_t

2位元組     uint16_t

4位元組     uint32_t

8位元組     uint64_t

當然有符號的就是 int8_t 這樣的表示。

那麼一元運算子是什麼意思呢?

int i = ~k;   //操作是數只有自己啊

int i = a&b; //這樣才是二元

按位很好理解就是每一位都操作一下,比如  a =0b11111001    b=0b00001110

例子:a & b 

1111 1001

&     0000 1110

----------------

0000 1000

這四個符號的優先順序:~    &    ^   |

避免歧義就不要吝嗇括號 ,當然看了半天,想到還有 ||   &&   這個操作是邏輯操作,結果是0 或者1,和這個不太一樣。

1.設定位

2.清楚位

3.測試位

假設我們的乙個8位暫存器儲存在unsigned char  x 中。[0-7位]

1.比如說讓乙個數的第四位設定為1。 我們只需把第4位 或(|)上1 即可.

x |=  0b0001 0000

x |=  0x0100

為了更通用的寫法,我們通常把第幾位當成乙個變數i 

x |=  (1<

2.比如說讓乙個數的第四位清零。 我們只需把第4位 &上0 即可。

x & 0b 1110 1111

x & 0x  ef

因為構造某一位為0,我們需要給其他位填充1。我們有一種更通用的做法。

~0 便是0xfffffffffffffffff 位數就看變數的型別了,跳一步直接用i表示,我們可以得出下面的式子

x &=   ~ 0x0010

x &=  ~ (1<

3.測試第4位是否為1   

if( x & 0x0010 )

==>

if(   x &  (1<

#define getbit(dat,i)   (  (dat)&( 0x1<<(i) )?1:0    )

#define setbit(dat,i) ( (dat)|=( 0x1<<(i) ) )

#define clearbit(dat,i) ( (dat)&= ~( 0x01<<(i) ) )

這裡沒有考慮dat是什麼型別,可以c語言的關鍵字獲取到型別後,強轉一下,效果應該更好。

extern __inline__ int set_bit(int nr,long * addr)

假設*addr = 0, nr = 3;則執行結果為1000(二進位制數)

(1)如果nr大於32,則addr移動(nr/32)位數,指向下乙個long 的開始位。nr>>5也就是nr除以2的5次方,等於nr/32.    

(2)擷取nr的低5位,然後將1左移(低5位對應的10進製數)。這樣做是為了解決當nr大於31時,將1左移32位或者更多將會導致溢位(因為mask是int型,而int型在linux中是32位長)。

為什麼特意擷取nr的低5位呢,我認為是經驗,你可以試試看,比如我傳遞給nr的值為33,則mask的值為  

mask = 1 << (33 & 0x1f);   計算結果為mask=1<<1,mask=0x10,

另外說明一下:

0x1f(16進製制) = 11111(2進製) = 31(10進製)

對於1.2兩部非常的佩服,統一了是否移位大於32位的操作

感覺指標運用的爐火純青,關於x位處理器long的實現應該是x位吧。

通過步驟1我們知道addr指向32位的位置,那麼 (

*addr |= mask

)就會把第33位置1了。

首先用按位與清除

使用按位或存入

比如將101(0x5) 存入 4-6位

i=(i & ~0x70 )|( 0x5 >>4)

這裡還需要歸納一下 0x70 因為是清理3位 那麼 0x7左移動4位

i= (i & ~(0x7 >>4)  | 0x5 >>4)

那麼我們只需要清理幾位,放到第幾位(最低位),和存入的值 即可。

#define setnbit(dat,n,low_index,value) \

(dat) = ( (dat) & ~( mask <<(low_index) ) | ((value) <<(low_index)) ); \

}

例:獲取 3-5位

移位到最位數最右端,然後取n位

( i >>3 ) &0x7

#define getnbit(dat,n,low_index,value)\

value = ( (dat)>>(low_index) &(mask) );\

}

感覺這種巨集的實現有點蹩腳,還是用函式實現比較看起來爽一點。

void setnbit(unsigned *dat, int n, int low_index, int value)

*dat = *dat & (~(mask << low_index)) | (value << low_index);

}void getnbit(unsigned *dat, int n, int low_index, int *value)

*value = (*dat >> low_index) & mask;

}

C語言位操作

在電腦程式中,資料的位是可以操作的最小資料單位,理論上可以用 位運算 來 完成所有的運算和操作。一般的位操作是用來控制硬體的,或者做資料變換使用,但是,靈活的位操作可以有效地提高程式執行的效率。c語言提供了位運算的功 能,這使得c語言也能像組合語言一樣用來編寫系統程式。位運算子c語言提供了六種位運算...

c語言位操作

位運算 and與 有一位為0 運算就為0 想獲取高四位,a a 0xf0 簡寫 a 0xf0 清零 一三五七位清零 a a 0x55 檢測位 檢測第三位 a a 0x04 遮蔽高四位,保留低4 位 a a 0x0f 統計2進製a中1的個數 1 include2 int main 3 11 print...

C語言位操作

朱老師物聯網大講堂 學習筆記 1 位與 只有1 1才是1,其餘全是0,位或 只有0 0才是0,其餘全是1,位取反 按位操作,位異或 1 0 1 0 1 1,也就是說相異結果是1,與1異或會取反,與0異或無變化,移位分 左 右 移,物件分 有 無符號數,只說一點 有符號數右移左側補符號位,叫算術移位,...