可以使用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 中函式引數的形參列表可以有佔位引數,用來作佔位,呼叫函式時須填補...