Objective C中的位運算子用法

2021-07-29 11:51:09 字數 4786 閱讀 2868

符號運算

&按位與

|按位或

^按位異或

~一次求反

<<

向左移位

>>

向右移位

表中列出的所有運算子,除一次求反運算子(~)外,都是二元運算子,因此需要兩個運算數。位運算子可處理任何型別的整型值,但不能處理浮點值。

1、按位運算子

對兩個值執行與運算時,會逐位比較兩個值的二進位制表示。第乙個值與第二個值對應位都為1時,在結果的對應位上就會得到1,其他的組合在結果中都得到0。如果b1和b2表示兩個運算數的對應位,那麼下表(稱為真值表)就顯示了在b1和b2所有可能值下對b1和b2執行與操作的結果。

b1   b2   b1 & b2

——————————

0     0         0

0     1         0

1     0         0

1     1         1

例如,如果w1和w2都定義為short int , w1等於十六進製制的15 ,  w2等於十六進製制的0c,那麼以下c語句會將值0x04指派給w3。

w3 = w1 & w2;

將w1、w2和w3都表示為二進位制後可更清楚地看到此過程,假設所處理的short int大小為16位。

w1    0000 0000 0001 0101     0x15

w2    0000 0000 0000 1100   & 0x0c

————————————————————

w3    0000 0000 0000 0100     0x04

按位與運算經常用於遮蔽運算。就是說,這個運算子可輕易地將資料項的特定位設定為0。例如,語句

w3 = w1 & 3;

將w1與常量3按位與所得的值指派給w3。它的作用是將w3中的全部位(而非最右邊的兩位)設定為0,並保留w1中最左邊的兩位。

與objective-c中使用的所有二元運算子相同,通過新增等號,二元位運算子可同樣用作賦值運算子。因此語句

word &= 15;

與下列語句

word = word & 15;

執行相同的功能。

此外,它還能將word的全部位設定為0,但最右邊的四位除外。

2、按位或運算子

在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;

我們在後面會提供乙個程式例子,演示如何使用按位或運算子。

3、按位異或運算子

按位異或運算子,通常稱為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

1、一次求反運算

一次求反運算子是一元運算子,它的作用僅是對運算數的位「翻轉」。將運算數的每個是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,可將乙個所有位都是1、但最右邊的位是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

// bitwise operators illustrated

#import

intmain (intargc,char*argv)

結果輸出:

a0a00000 ffffa0a0 5f5fa0a0

5f5f5f5f ffff ffff8888

0 a0a0 fffff7f7

a0a0a0a0 ffffa0a0

ffffa0a0 a0a00000

對**中的每個運算都演算一遍,確定你理解了這些結果是如何得到的。

在第四個nslog呼叫中,需要注意重要的一點,即按位與運算子的優先順序要高於按位或運算子,因為這會實際影響表示式的最終結果值。

第五個nslog呼叫展示了demorgan的規則:~(~a & ~b)等於a | b,~(~a | ~b)等於a & b。

2、向左移位運算子

對值執行向左移位運算時,按照字面的意思,值中包含的位將向左移動。與該操作關聯的是該值要移動的位置(或位)數目。超出資料項的高位的位將丟失,而從低位移入的值總為0。因此,如果w1等於3,那麼表示式

w1 = w1 << 1;

可同樣表示成

w1 <<= 1;

結果就是3向左移一位,這樣產生的6將賦值給w1。

w1              ... 0000 0011 0x03

w1 << 1      ... 0000 0110 0x06

3、向右移位運算子

顧名思義,向右移位運算子(>>)把值的位向右移動。從值的低位移出的位將丟失。把無符號的值向右移位總是左側(就是高位)移人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中的位運算子用法

符號運算 按位與 按位或 按位異或 一次求反 向左移位 向右移位 表中列出的所有運算子,除一次求反運算子 外,都是二元運算子,因此需要兩個運算數。位運算子可處理任何型別的整型值,但不能處理浮點值。1 按位運算子 對兩個值執行與運算時,會逐位比較兩個值的二進位制表示。第乙個值與第二個值對應位都為1時,...

Objective C使用位運算設計可複選的列舉

在軟體開發中,列舉是我們會經常會用到的一種程式設計方式,通過列舉,可以使我們的 更具可讀性與統一性。通常情況下,我們會通過typedef來定義一種列舉的型別來使用。例如 12 3 4 5 typedefenummyenum 我們可以在函式的引數中來使用它 12 3 4 5 6 7 8 9 10 11...

Objective C位運算子 一次求反運算子

一次求反運算子是一元運算子,它的作用僅是對運算數的位 翻轉 將運算數的每個是1的位翻轉為0,而將每個是0的位翻轉為1。下面是真值表 b1 b1 0 1 1 0 如果不知道運算中數值的準確位大小,那麼一次求反運算子非常有用,使用它可讓程式不會依賴於整數資料型別的特定大小。例如,要將型別為int的w1的...