目錄
C語言中六種位運算符:
一、位移運算符
1、移位運算符簡介
2、先要了解一點
3、 << 左移運算符
4、>>右移運算符
5、警告
二、
1、& 按位與
2、| 按位或
3、^ 按位異或
4、~ 取反
4、例子?
C語言中六種位運算符:
& 按位與
| 按位或
^ 按位異或
~取反
>>右移
<<左移
位運算符用來對二進制位進行操作,C語言中提供了如上表所示的位運算符。
位運算符中,除 ~ (取反)以外,其余均為雙目運算符。
位運算符操作數(shù)只能為整型和字符型數(shù)據(jù)。
一、位移運算符
1、移位運算符簡介
在C語言中,移位運算符有雙目移位運算符:<<(左移)和>>(右移)。
左移運算是將一個二進制位的操作數(shù)按指定移動的位數(shù)向左移動,移出位被丟棄,右邊移出的空位一律補 0 。
右移運算是將一個二進制位的操作數(shù)按指定移動的位數(shù)向右移動,移出位被丟棄,左邊移出的空位一律補 0 ,或者補符號位,這由不同的機器而定。在使用補碼作為機器數(shù)的機器中,正數(shù)的符號位為? 0 ,負數(shù)的符號位為 1 。
聽不懂是吧,接下來且聽我詳解。
2、先要了解一點
首先,要了解原碼、反碼、補碼(簡單說一下)
整數(shù)在內存中存儲的形式是補碼的二進制。
整數(shù)的二進制表示:有3種(原碼、反碼、補碼)
原碼:直接根據(jù)數(shù)值寫出的二進制序列就是原碼(32位)
反碼:原碼的符號位不變,其他位按位取反就是反碼
補碼:反碼加1,就是補碼
對于正整數(shù)的原碼、反碼、補碼都相同;負數(shù)是存放在二進制的補碼中,負整數(shù)的原碼、反碼、補碼都不相同。
?
?例如:1(正整數(shù)的原碼、反碼、補碼都相同)
原碼:0000000 00000000 00000000 00000001
反碼:0000000 00000000 00000000 00000001
補碼:0000000 00000000 00000000 00000001
最高位為0 ,也是符號位
例如:-1(負整數(shù)的原碼、反碼、補碼都相同
原碼:10000000 00000000 00000000 00000001
反碼:11111111 11111111 11111111 11111110(按位取反,符號位不變)
補碼:11111111 11111111 11111111 11111111(反碼加1)
?最高位為1,也是符號位
3、 << 左移運算符
先上代碼(只演示負整數(shù)的,看完正整數(shù)的也會了,正整數(shù)的比較簡單)
#include<stdio.h>
int main()
{
int a = -5;
int b = a << 1;
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
結果是 -10
這是為什么呢,原因如下:?
規(guī)則:左移運算是將一個二進制位的操作數(shù)按指定移動的位數(shù)向左移動,移出位被丟棄,右邊移出的空位一律補0。
簡單說就是:左邊丟棄,右邊補0
先寫出 -5 的補碼
原碼:10000000 00000000 00000000 00000101 (最高位為1)
反碼:11111111 11111111 11111111 11111010 (按位取反,符號位不變)
補碼:11111111 11111111 11111111 11111011 (反碼加1)
補碼向左移動一位,左邊去掉,右邊補0,如圖:
此時得到的是補碼,還要反推原碼才能打印
補碼:11111111 11111111 11111111 11110110
反碼:11111111 11111111 11111111 11110101(補碼 -1 得到反碼)
原碼:10000000 00000000 00000000 00001010(按位取反得到原碼)
此時得到的原碼就可以打印了,結果是 -10
注:此時的 a 沒有改變,依舊是 -5
4、>>右移運算符
先上代碼(只演示負整數(shù)的,看完正整數(shù)的也會了,正整數(shù)的比較簡單)
#include<stdio.h>
int main()
{
int a = -5;
int b = a >> 1;
printf("%d\n", a);
printf("%d\n", b);
return 0;
}
結果是:-3
?這是為什么,原因如下:?
右移運算是將一個二進制位的操作數(shù)按指定移動的位數(shù)向右移動,移出位被丟棄,左邊移出的空位一律補0,或者補符號位,這由不同的機器而定。在使用補碼作為機器數(shù)的機器中,正數(shù)的符號位為 0 ,負數(shù)的符號位為 1 。
簡單說就是:(分為 2 種)
1. 邏輯右移
左邊用0填充,右邊丟棄。
2. 算術右移
左邊用原該值的符號位填充,右邊丟棄。到底是邏輯右移還是算術右移取決于編譯器
我當前使用的編譯器,它采用的是算術右移
先寫出 -5 的補碼
原碼:10000000 00000000 00000000 00000101 (最高位為1)
反碼:11111111 11111111 11111111 11111010 (按位取反,符號位不變)
補碼:11111111 11111111 11111111 11111011 (反碼加1)
補碼向右移動一位,右邊丟棄,左邊補符號位,如圖:
???此時得到的是補碼,還要反推原碼才能打印
補碼:11111111 11111111 11111111 11111101
反碼:11111111 11111111 11111111 11111100(補碼 -1 得到反碼)
原碼:10000000 00000000 00000000 00000011(按位取反得到原碼)
此時得到的原碼就可以打印了,結果是 -3
注:此時的 a 沒有改變,依舊是 -5
5、警告
警告?:
對于移位運算符,不要移動負數(shù)位,這個是標準未定義的。
例如:
int a = 5;
int b = a >> -1 //error
二、
1、& 按位與
先上代碼:
#include<stdio.h>
int main()
{
int a = 5;
int b = -2;
int c = a & b;
printf("%d\n", c);
return 0;
運行結果是:4
??這是為什么,原因如下:
規(guī)則:兩個二進制操作數(shù)對應位同為 1 ,結果位才為 1 ,其余情況為 0 。
先寫出 5,-2 的補碼
5 的補碼:00000000 00000000 00000000 00000101
-2 的原碼:10000000 00000000 00000000 00000010
-2 的反碼:11111111 11111111 11111111 11111101
-2 的補碼:11111111 11111111 11111111 11111110
兩個二進制操作數(shù)對應位同為 1 ,結果 位 才為 1 ,其余情況為 0?
? 5 的補碼:00000000 00000000 00000000 00000101
-2 的補碼:11111111 11111111 11111111 11111110
5 & -2 的補碼:00000000 00000000 00000000 00000100
此時得到的是補碼,要原碼才能打印
5 &- 2 的原碼:00000000 00000000 00000000 00000100
(正整數(shù)原、反、補相同)
此時打印結果是:4
2、| 按位或
先上代碼
#include<stdio.h>
int main()
{
int a = 5;
int b = -2;
int c = a | b;
printf("%d\n", c);
return 0;
}
結果是:-1
???這是為什么,原因如下:
規(guī)則:兩個二進制操作數(shù)對應位只要有一個為 1 ,結果 位 就為 1 ,其余情況為 0?
先寫出 5,-2 的補碼
? 5 的補碼:00000000 00000000 00000000 00000101
-2 的原碼:10000000 00000000 00000000 00000010
-2 的反碼:11111111 11111111 11111111 11111101
-2 的補碼:11111111 11111111 11111111 11111110
兩個二進制操作數(shù)對應位只要有一個為 1 ,結果 位 就為 1 ,其余情況為 0?
5 的補碼:00000000 00000000 00000000 00000101
-2 的補碼:11111111 11111111 11111111 11111110
5 | -2 的補碼:11111111 11111111 11111111 11111111
此時得到的是補碼,需要原碼才能打印
5 | -2 的補碼:11111111 11111111 11111111 11111111
5 | -2 的反碼:11111111 11111111 11111111 11111110
5 | -2 的原碼:10000000 00000000 00000000 00000001
此時打印結果是:-1
3、^ 按位異或
先上代碼
#include<stdio.h>
int main()
{
int a = 5;
int b = -2;
int c = a ^ b;
printf("%d\n", c);
return 0;
}
結果是:-5
??這是為什么,原因如下:
規(guī)則:兩個二進制操作數(shù)對應 位 相同為 0 ,不同為 1
先寫出 5,-2 的補碼
? 5 的補碼:00000000 00000000 00000000 00000101
-2 的原碼:10000000 00000000 00000000 00000010
-2 的反碼:11111111 11111111 11111111 11111101
-2 的補碼:11111111 11111111 11111111 11111110
兩個二進制操作數(shù)對應 位 相同為 0 ,不同為 1
? 5 的補碼:00000000 00000000 00000000 00000101
-2 的補碼:11111111 11111111 11111111 11111110
5 ^ -2 的補碼:11111111 11111111 11111111 11111011
此時得到的是補碼,需要原碼才能打印
5 ^ -2 的補碼:11111111 11111111 11111111 11111011
5 ^ -2 的反碼:11111111 11111111 11111111 11111010
5 ^ -2 的原碼:10000000 00000000 00000000 00000101
此時打印結果是:-5
4、~ 取反
~ (取反)這是一個單目操作符,先上代碼
#include<stdio.h>
int main()
{
int a = 5;
int c = ~a;
printf("%d\n", c);
return 0;
}
?結果是:-6
??這是為什么,原因如下:
規(guī)則:一個二進制操作數(shù),對應位為 0 ,結果位為 1 ;對應位為 1 ,結果位為 0
作用是將每位二進制取反
先寫出 5 的補碼?
? 5 的補碼:00000000 00000000 00000000 00000101
?對應位為 0 ,結果位為 1 ;對應位為1,結果位為 0
? 5 的補碼:00000000 00000000 00000000 00000101
取反:11111111 11111111 11111111 11111010
?此時得到的是補碼,需要原碼才能打印
取反后(補碼):11111111 11111111 11111111 11111010
反碼:11111111 11111111 11111111 11111001
原碼:10000000 00000000 00000000 00000110
此時打印的結果是:-6
4、例子?
例:不能創(chuàng)建臨時變量(第三個變量),實現(xiàn)兩個數(shù)的交換
很容易想到的代碼是兩個數(shù)相減,代碼如下:
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a + b;
b = a - b;
a = a - b;
printf("a = %d b = %d\n", a, b);
return 0;
}
但是這種代碼有局限性,當 a 和 b 這兩個數(shù)很大的時候,加起來超過了 int 的范圍,代碼就失效了
另一種的方法不易想到,就是用位操作符來實現(xiàn),代碼如下:
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d b = %d\n", a, b);
return 0;
}
為什么可以交換 a 和 b ,原因留給你自己琢磨,上面已經介紹過 ^ (按位異或)了
三、最后
文章到這就結束了,希望對你有幫助,覺得文章不錯就點個贊吧。文章來源:http://www.zghlxwxcb.cn/news/detail-739720.html
文章有什么問題可以留言,感謝支持!!?文章來源地址http://www.zghlxwxcb.cn/news/detail-739720.html
到了這里,關于【C語言初階】操作符之 位運算符詳解(“ << ”,“ >> ”,“ & ”,“ | ”,“ ^ ”,“ ~ ”)的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!