C C 學習筆記 C提高 位運算

2021-10-03 15:30:19 字數 3347 閱讀 5583

可以使用c對變數中的個別位進行操作。您可能對人們想這樣做的原因感到奇怪。這種能力有時確實是必須的,或者至少是有用的。c提供位的邏輯運算子和移位運算子。在以下例子中,我們將使用二進位制計數法寫出值,以便您可以了解對位發生的操作。在乙個實際程式中,您可以使用一般的形式的整數變數或常量。例如不適用00011001的形式,而寫為25或者031或者0x19.在我們的例子中,我們將使用8位數字,從左到右,每位的編號是7到0。

4個位運算子用於整型資料,包括char.將這些位運算子成為位運算的原因是它們對每位進行操作,而不影響左右兩側的位。請不要將這些運算子與常規的邏輯運算子(&& 、||和!)相混淆,常規的位的邏輯運算子對整個值進行操作。

一元運算子~將每個1變為0,將每個0變為1,如下面的例子:

~

(10011010

)01100101

假設a是乙個unsigned char,已賦值為2.在二進位制中,2是00000010.於是-a的值為11111101或者253。請注意該運算子不會改變a的值,a仍為2。

unsigned

char a =2;

//00000010

unsigned

char b =

~a;//11111101

printf

("ret = %d\n"

, a)

;//ret = 2

printf

("ret = %d\n"

, b)

;//ret = 253

二進位制運算子&通過對兩個運算元逐位進行比較產生乙個新值。對於每個位,只有兩個運算元的對應位都是1時結果才為1。

(

10010011)&

(00111101)=

(00010001

)

c也有乙個組合的位與-賦值運算子:&=。下面兩個將產生相同的結果:

val &

=0377

val = val &

0377

二進位制運算子|通過對兩個運算元逐位進行比較產生乙個新值。對於每個位,如果其中任意運算元中對應的位為1,那麼結果位就為1.

(

10010011)|

(00111101)=

(10111111

)

c也有組合位或-賦值運算子: |=

val |

=0377

val = val |

0377

二進位制運算子^對兩個運算元逐位進行比較。對於每個位,如果運算元中的對應位有乙個是1(但不是都是1),那麼結果是1.如果都是0或者都是1,則結果位0.

(

10010011)^

(00111101)=

(10101110

)

c也有乙個組合的位異或-賦值運算子: ^=

val ^

=0377

val = val ^

0377

開啟位

已知:10011010:

將位2開啟

flag | 10011010

(

10011010)|

(00000100)=

(10011110

)

將所有位開啟。

flag | ~flag

(

10011010)|

(01100101)=

(11111111

)

關閉位

flag & ~flag

(

10011010)&

(01100101)=

(00000000

)

轉置位

轉置(toggling)乙個位表示如果該位開啟,則關閉該位;如果該位關閉,則開啟。您可以使用位異或運算子來轉置。其思想是如果b是乙個位(1或0),那麼如果b為1則b1為0,如果b為0,則1b為1。無論b的值是0還是1,0^b為b.

flag ^ 0xff

(

10010011)^

(11111111)=

(01101100

)

交換兩個數不需要臨時變數
//a ^ b = temp;

//a ^ temp = b;

//b ^ temp = a

(10010011)^

(00100110)=

(10110101)(

10110101)^

(00100110

)10010011

int a =10;

int b =

30;

現在讓我們了解一下c的移位運算子。移位運算子將位向左或向右移動。同樣,我們仍將明確地使用二進位制形式來說明該機制的工作原理。

左移運算子《將其左側運算元的值的每位向左移動,移動的位數由其右側運算元指定。空出來的位用0填充,並且丟棄移出左側運算元末端的位。在下面例子中,每位向左移動兩個位置。

(

10001010

)<<2(

00101000

)

該操作將產生乙個新位置,但是不改變其運算元。

1

<<1=

2;2<<1=

4;4<<1=

8;8<<2=

32

左移一位相當於原值*2.

右移運算子》將其左側的運算元的值每位向右移動,移動的位數由其右側的運算元指定。丟棄移出左側運算元有段的位。對於unsigned型別,使用0填充左端空出的位。對於有符號型別,結果依賴於機器。空出的位可能用0填充,或者使用符號(最左端)位的副本填充。

//有符號值

(10001010

)>>2(

00100010

)//在某些系統上的結果值

(10001010

)>>2(

11100010

)//在另一些系統上的解雇

//無符號值

(10001010

)>>2(

00100010

)//所有系統上的結果值

移位運算子能夠提供快捷、高效(依賴於硬體)對2的冪的乘法和除法。

number << n	number乘以2的n次冪

number >> n 如果number非負,則用number除以2的n次冪

C C 學習筆記 C提高 鍊錶

陣列和鍊錶的區別 陣列 一次性分配一塊連續的儲存區域。優點 隨機訪問元素效率高 缺點 1 需要分配一塊連續的儲存區域 很大區域,有可能分配失敗 2 刪除和插入某個元素效率低 鍊錶 無需一次性分配一塊連續的儲存區域,只需分配n塊節點儲存區域,通過指標建立關係。優點 1 不需要一塊連續的儲存區域 2 刪...

C C 學習筆記 C提高 函式指標和遞迴函式

通過什麼來區分兩個不同的函式?乙個函式在編譯時被分配乙個入口位址,這個位址就稱為函式的指標,函式名代表函式的入口位址。函式三要素 名稱 引數 返回值。c語言中的函式有自己特定的型別。c語言中通過typedef為函式型別重新命名 typedef intf int int f 為函式型別 typedef...

C 學習筆記之函式提高

c 學習筆記之函式提高 在c 中,函式中的形參列表中是可以預設值的。語法 返回值型別 函式名 引數 預設值 如果某個位置已經有了預設引數,那麼從這個位置往後,從左到右都必須有預設值。如果函式宣告有預設引數,函式實現就不能有預設引數 c 中函式引數的形參列表可以有佔位引數,用來作佔位,呼叫函式時須填補...