這篇文章咱們一塊兒來看看Objective-C位運算符。Objective-C語言中有各類各樣的運算符可處理數字中的特定位,以下表所示:html
符號 | 運算 |
& | 按位與 |
| | 按位或 |
^ | 按位異或 |
~ | 一次求反 |
<< | 向左移位 |
>> | 向右移位 |
表中列出的全部運算符,除一次求反運算符(~)外,都是二元運算符,所以須要兩個運算數。位運算符可處理任何類型的整型值,但不能處理浮點值。spa
一、按位運算符code
對兩個值執行與運算時,會逐位比較兩個值的二進制表示。第一個值與第二個值對應位都爲1時,在結果的對應位上就會獲得1,其餘的組合在結果中都獲得0。若是b1和b2表示兩個運算數的對應位,那麼下表(稱爲真值表)就顯示了在b1和b2全部可能值下對b1和b2執行與操做的結果。htm
b1 b2 b1 & b2
——————————
0 0 0
0 1 0
1 0 0
1 1 1blog
例如,若是w1和w2都定義爲short int , w1等於十六進制的15 , w2等於十六進制的0c,那麼如下C語句會將值0x04指派給w3。ci
w3 = w1 & w2;get
將w一、w2和w3都表示爲二進制後可更清楚地看到此過程,假設所處理的short int大小爲16位。it
w1 0000 0000 0001 0101 0x15
w2 0000 0000 0000 1100 & 0x0c
————————————————————
w3 0000 0000 0000 0100 0x04io
按位與運算常常用於屏蔽運算。就是說,這個運算符可輕易地將數據項的特定位設置爲0。例如,語句table
w3 = w1 & 3;
將w1與常量3按位與所得的值指派給w3。它的做用是將w3中的所有位(而非最右邊的兩位)設置爲0,並保留w1中最左邊的兩位。
與Objective-C中使用的全部二元運算符相同,經過添加等號,二元位運算符可一樣用做賦值運算符。所以語句
word &= 15;
與下列語句
word = word & 15;
執行相同的功能。
此外,它還能將word的所有位設置爲0,但最右邊的四位除外。
二、按位或運算符
在Objective-C中對兩個值執行按位或運算時,會逐位比較兩個值的二進制表示。此時,只要第一個值或者第二個值的相應位是1。那麼結果的對應位就是1。按位或操做符的真值表以下所示。
b1 b2 b1 | b2
———————————
0 0 0
0 1 1
1 0 1
1 1 1
因此,若是w1是short int,等於十六進制的19, w2也是short int,等於十六進制的6a,那麼對w1和vv2執行按位或會獲得十六進制的7b,以下所示:
w1 0000 0000 0001 1001 0x19
w2 0000 0000 0110 1010 | 0x6a
————————————————————
0000 0000 0111 1011 0x7b
按位或操做一般就稱爲按位OR,用於將某個詞的特定位設爲1。例如,如下語句將w1最右邊的三位設爲1,而無論這些位操做前的狀態是什麼都是如此。
w1 = w1 | 07;
固然,能夠在語句中使用特殊的斌值運算符,以下面的語句所示:
w1 |= 07;
咱們在後面會提供一個程序例子,演示如何使用按位或運算符。
三、按位異或運算符
按位異或運算符,一般稱爲XOR運算符,遵照如下規則:對幹兩個運算數的相應位,若是任何一個位是1,但不是二者全爲1,那麼結果的對應位將是1,不然是0。該運算符的真值表如
下所示:
b1 b2 b1 ^ b2
————————————
0 0 0
0 1 1
1 0 1
1 1 0
若是w1和w2分別等於十六進制的5e和d6,那麼w1與w2執行異或運算後的結果是十六進制值e8,以下所示:
w1 0000 0000 0101 1110 0x5e
w2 0000 0000 1011 0110 ^ 0xd6
——————————————————————
0000 0000 1110 1000 0xe8
本文就先講到這裏,對於Objective-C位運算符咱們下一篇繼續探討,下次主要討論一下Objective-C位運算符中的一次求反、向左移位運算、向右移位運算,下回見。
一、一次求反運算
一次求反運算符是一元運算符,它的做用僅是對運算數的位「翻轉」。將運算數的每一個是1的位翻轉爲0,而將每一個是0的位翻轉爲1。此處提供真值表只是爲了保持內容的完整性。
b1 ~b1
——————
0 1
1 0
若是w1是short int, 16位長,等於十六進制值a52f,那麼對該值執行一次求反運算會獲得十六進制值5ab0:
w1 1010 0101 0010 1111 0xa52f
~w1 0101 1010 1101 0000 0x5ab0
若是不知道運算中數值的準確位大小,那麼一次求反運算符很是有用,使用它可以讓程序不會依賴於整數數據類型的特定大小。例如,要將類型爲int的w1的最低位設爲0,可將一個全部位都是一、但最右邊的位是0的int值與w1進行與運算。因此像下面這樣的C語句在用32位表示整數的機器上可正常工做。
w1 &= 0xFFFFFFFE;
若是用
w1 &= ~1;
替換上面的語句,那麼在任何機器上w1都會同正確的值進行與運算。
這是由於這條語句會對1求反,而後在左側會加入足夠的1,以知足int的大小要求(在32位機器上,會在左側的31個位上加入1)。
如今,顯示一個實際的程序例子,說明各類位運算符的用途
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
結果輸出:
a0a00000 ffffa0a0 5f5fa0a0
5f5f5f5f ffff ffff8888
0 a0a0 fffff7f7
a0a0a0a0 ffffa0a0
ffffa0a0 a0a00000
對代碼中的每一個運算都演算一遍,肯定你理解了這些結果是如何獲得的。
在第四個NSLog調用中,須要注意重要的一點,即按位與運算符的優先級要高於按位或運算符,由於這會實際影響表達式的最終結果值。
第五個NSLog調用展現了DeMorgan的規則:~(~a & ~b)等於a | b,~(~a | ~b)等於a & b。
二、向左移位運算符
對值執行向左移位運算時,按照字面的意思,值中包含的位將向左移動。與該操做關聯的是該值要移動的位置(或位)數目。超出數據項的高位的位將丟失,而從低位移入的值總爲0。所以,若是w1等於3,那麼表達式
w1 = w1 << 1;
可一樣表示成
w1 <<= 1;
結果就是3向左移一位,這樣產生的6將賦值給w1。
w1 ... 0000 0011 0x03
w1 << 1 ... 0000 0110 0x06
三、向右移位運算符
顧名思義,向右移位運算符(>>)把值的位向右移動。從值的低位移出的位將丟失。把無符號的值向右移位老是左側(就是高位)移人0。對於有符號值而言,左側移入1仍是0依賴於被移動數字的符號,還取決於該操做在計算機上的實現方式。若是符號位是0(表示該值是正的),無論哪一種機器都將移人0。然而,若是符號位是1,那麼在一些計算機上將移人1,而其餘計算機上則移入0。前一類型的運算符一般稱爲算術右移,然後者一般稱爲邏輯右移。
若是w1是unsigned int,用32位表示它而且它等於+六進制的F777EE22,那麼使用語句
w1 >>= 1;
將w1右移一位後,w1等於十六進制的7BBBF711,以下所示:
w1 1111 0111 0111 0111 1110 1110 0010 0010 0xF777EE22
w1 >> 1 0111 1011 1011 1011 1111 0111 0001 0001 0x7BBBF711
若是將w1聲明爲(有符號)的short int,在某些計算機上會獲得相同的結果;而在其餘計算機上,若是將該運算做爲算術右移來執行,結果將會是FBBBF711。
應該注意到,若是試圖用大於或等於該數據項的位數將值向左或向右移位,那麼該Objective-C語言並不會產生規定的結果。所以,例如計算機用32位表示整數,那麼把一個整數向左或向右移動32位或更多位時,並不會在計算機上產生規定的結果。還注意到,若是使用負數對值移位時,結果將一樣是未定義的。
好了,經過這兩篇文章的介紹,你們應該對Objective-C位運算符有必定了解了吧。