亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

C 語言中的位運算符

在 C 語言中,相同的數字可以用不同的數制來表示。也就是十進制的數字可以等價的表示為二進制或者十六進制。那么對于二進制來說,可以進行逐個數字之間,也就是每一個數字位的運算。這種運算也廣泛的存在我們日程使用的數字電路中。其實計算機的運算原理最底層就是位運算,也就是 0 和 1 的運算。

1. 位運算符

運算符 作用 示例
& 位與 a&b
| 位或 a|b
^ 位異或 a^b
~ 位非 ~b
<< 位左移 a<<b
>> 位右移 a>>b

對于位運算中的與、或、異或可以通過下面的表格來闡明。

x y x & y x | y x ^ y
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0

對于非操作符有下表的結果。

x ~x
0 1
1 0

移位操作就是將位向左或者向右移動,空位用 0 來補齊。

2. 示例

# include <stdio.h>

int main()
{
    int x,y,z;
    x=10; // 10 = 1010
    y=15; // 15 = 1111
    z=x&y;
    printf("x & y = %d\n", z);
    z=x|y;
    printf("x | y = %d\n", z);
    z=x^y;
    printf("x ^ y = %d\n", z);
    z=~x;
    printf("~ x = %d\n", z);
    z=~y;
    printf("~ y = %d\n", z);
    z=x<<2;
    printf("x << 2 = %d\n", z);
    z=y>>2;
    printf("x >> 2 = %d\n", z);
    return 0;
}

運行結果如下:

x & y = 10
x | y = 15
x ^ y = 5
~ x = -11
~ y = -16
x << 2 = 40
x >> 2 = 3

那么我們分析一下這些結果。

     10 = 1 0 1 0
     15 = 1 1 1 1
10 & 15 = 1 0 1 0

按照上節的表格計算后,發現 10 與 15 進行位與計算后,結果為 10 。

     10 = 1 0 1 0
     15 = 1 1 1 1
10 | 15 = 1 1 1 1

按照上節的表格計算后,發現 10 與 15 進行位或計算后,結果為 15 。

     10 = 1 0 1 0
     15 = 1 1 1 1
10 ^ 15 = 0 1 0 1

按照上節的表格計算后,發現 10 與 15 進行位異或計算后,結果為 5 。

  10 = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0
~ 10 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 0 1

因為一個整數是由 4 個字節組成,每個字節是 8 位,因此
在 1010 前還有 28 個 0 存在。將這些 0 全部變為 1 ,這時的數字代表 -11。

  15 = 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1
~ 15 = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0

在 1111 前還有 28 個 0 存在。將這些 0 全部變為 1 ,這時的數字代表 -40。

     10 =     1 0 1 0
10 << 2 = 1 0 1 0 0 0

把 10 向左移動兩位,右面的空余位置用 0 補齊。

Tips:請特別注意,在向左移位的過程中,如果左移的位數超出數據的存儲最大位數,那么將產生錯誤。

下面的示例程序展示了這種錯誤。

# include <stdio.h>

int main()
{
    int x,y,z;
    x=10; // 10 = 1010
    z=x<<200;
    printf("x << 200 = %d\n", z);
    return 0;
}

顯然超過了 int 類型可以表示的最大位數。

在編譯的時候,會出現如下的錯誤。

test.c: In function ‘main’:
test.c:7:8: warning: left shift count >= width of type [-Wshift-count-overflow]
     z=x<<200;
     15 = 1 1 1 1
15 >> 2 = 0 0 1 1

把 15 向右移動兩位,左面的空位用 0 補齊。

3. 小結

位運算作為一種直接的,符合數字電路邏輯的運算,廣泛的存在于我們的生活中。在編程語言中,通過位運算可以方便的獲得如網絡地址的計算,還有我們日常的一些加減乘除都是可以通過位運算來實現的。只不過很多運算由于表示不直觀,容易出錯,所以還是使用了普通的算數運算符等來進行計算。

同時也要區分,位運算與我們介紹的邏輯運算符很相似,所以請大家注意區分。