c的位操作
一、位的概念
我們知道,在計算機中,一字節占8位(現在的某些電腦也有占16位的),這樣表示的數的范圍為0-255,
也即00000000-11111111。位就是里面的0和1。
char c=100;
實際上c應該是01100100,正好是64H。其中高位在前,低位在后。
| |
第7位 第0位
二、位邏輯運算符
符號 描述
& 按位與
| 按位或
^ 按位異或
~ 按位取反
表中除去最后一個運算符是單目運算符,其他都是雙目運算符。這些運算符只能用于整型表達式。位邏輯運算符通常用于對整型變量進行位的設置、清零、取反、以及對某些選定的位進行檢測。在程序中一般被程序員用來作為開關標志。較低層次的硬件設備驅動程序,經常需要對輸入輸出設備進行位操作。
& 運算的規則是當兩個位都為1時,結果為1,否則為0;
| 運算的規則是當兩個位都為0時,結果為0,否則為1;
^ 運算的規則是當兩個位相同時,結果為0,否則為1;
~ 運算的規則是當為1時結果為0,當為0時結果為1。
1. 按位與運算 按位與運算符"&"是雙目運算符。其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1 ,否則為0。參與運算的數以補碼方式出現。
例如:9&5可寫算式如下:?
00001001 (9的二進制補碼)&00000101 (5的二進制補碼)
00000001 (1的二進制補碼)可見9&5=1。
按位與運算通常用來對某些位清0或保留某些位
例如:把a 的高八位清 0 , 保留低八位,?
可作 a&255 運算 ( 255 的二進制數為0000000011111111)。
應用:
a. 清零特定位 (mask中特定位置0,其它位為1,s=s&mask)
b. 取某數中指定位 (mask中特定位置1,其它位為0,s=s&mask)
2. 按位或運算 按位或運算符“|”是雙目運算符。其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有一個為1時,結果位就為1。參與運算的兩個數均以補碼出現。
例如:9|5可寫算式如下:
00001001|00000101
00001101 (十進制為13)可見9|5=13
應用:
常用來將源操作數某些位置1,其它位不變。 (mask中特定位置1,其它位為0 s=s|mask)
3. 按位異或運算 按位異或運算符“^”是雙目運算符。其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。參與運算數仍以補碼出現,
例如:9^5可寫成算式如下:
00001001^00000101 00001100 (十進制為12)
應用:
a.?使特定位的值取反?(mask中特定位置1,其它位為0 s=s^mask)
b.?不引入第三變量,交換兩個變量的值?(設 a=a1,b=b1)
目標操作操作后狀態
a=a1^b1 a=a^b a=a1^b1,b=b1
b=a1^b1^b1 b=a^b a=a1^b1,b=a1
a=b1^a1^a1 a=a^b a=b1,b=a1
4. 求反運算 求反運算符~為單目運算符,具有右結合性。 其功能是對參與運算的數的各二進位按位求反。
例如:~9的運算為:?
~(0000000000001001)結果為:1111111111110110
三、位移運算符
符號 描述
<< 左移
>> 右移
5. 左移運算 左移運算符“<<”是雙目運算符。其功能把“<< ”左邊的運算數的各二進位全部左移若干位,由“<<”右邊的數指定移動的位數,?高位丟棄,低位補0。 其值相當于乘2。
例如: a<<4 指把a的各二進位向左移動4位。
如a=00000011(十進制3),左移4位后為00110000(十進制48)。
6. 右移運算 右移運算符“>>”是雙目運算符。其功能是把“>> ”左邊的運算數的各二進位全部右移若干位,“>>”右邊的數指定移動的位數。其值相當于除2。
例如:設 a=15,a>>2 表示把000001111右移為00000011(十進制3)。
對于左邊移出的空位,如果是正數則空位補0,若為負數,可能補0或補1,這取決于所用的計算機系統。移入0的叫邏輯右移,移入1的叫算術右移,Turbo C采用邏輯右移。
main(){
unsigned a,b;
printf("input a number: ");
scanf("%d",&a);
b=a>>5;
b=b&15;
printf("a=%d b=%d ",a,b);
}
舉例:輸入一個整數,判斷這個數中有幾個二進制位1?例如輸入67,輸出結果應該為3。因為67的相應二進制數為00000000 01000011(0043H),有3個1出現。
分析:要判斷是不是1,只需要判斷該位與1與以后是不是1就可以知道。一個整數,判斷16次即可。
int main(int argc, char *argv[])
{
int num, i, cnt = 0;
scanf("%d", &num);
for(i = 0; i < 16; i++)
{
if(num & 1 == 1) /* 判斷最低位是不是1 */
cnt++;?
num >>= 1; /* num右移1位 */
}
printf("%d\n", cnt);
return 0;
}
這樣每次都判斷最低位是不是1,判斷完以后,讓前面的右移一位即可。 注:文章轉自http://blog.chinaunix.net/uid-26495963-id-3065899.html
我們知道,在計算機中,一字節占8位(現在的某些電腦也有占16位的),這樣表示的數的范圍為0-255,
也即00000000-11111111。位就是里面的0和1。
char c=100;
實際上c應該是01100100,正好是64H。其中高位在前,低位在后。
| |
第7位 第0位
二、位邏輯運算符
符號 描述
& 按位與
| 按位或
^ 按位異或
~ 按位取反
表中除去最后一個運算符是單目運算符,其他都是雙目運算符。這些運算符只能用于整型表達式。位邏輯運算符通常用于對整型變量進行位的設置、清零、取反、以及對某些選定的位進行檢測。在程序中一般被程序員用來作為開關標志。較低層次的硬件設備驅動程序,經常需要對輸入輸出設備進行位操作。
& 運算的規則是當兩個位都為1時,結果為1,否則為0;
| 運算的規則是當兩個位都為0時,結果為0,否則為1;
^ 運算的規則是當兩個位相同時,結果為0,否則為1;
~ 運算的規則是當為1時結果為0,當為0時結果為1。
1. 按位與運算 按位與運算符"&"是雙目運算符。其功能是參與運算的兩數各對應的二進位相與。只有對應的兩個二進位均為1時,結果位才為1 ,否則為0。參與運算的數以補碼方式出現。
例如:9&5可寫算式如下:?
00001001 (9的二進制補碼)&00000101 (5的二進制補碼)
00000001 (1的二進制補碼)可見9&5=1。
按位與運算通常用來對某些位清0或保留某些位
例如:把a 的高八位清 0 , 保留低八位,?
可作 a&255 運算 ( 255 的二進制數為0000000011111111)。
應用:
a. 清零特定位 (mask中特定位置0,其它位為1,s=s&mask)
b. 取某數中指定位 (mask中特定位置1,其它位為0,s=s&mask)
2. 按位或運算 按位或運算符“|”是雙目運算符。其功能是參與運算的兩數各對應的二進位相或。只要對應的二個二進位有一個為1時,結果位就為1。參與運算的兩個數均以補碼出現。
例如:9|5可寫算式如下:
00001001|00000101
00001101 (十進制為13)可見9|5=13
應用:
常用來將源操作數某些位置1,其它位不變。 (mask中特定位置1,其它位為0 s=s|mask)
3. 按位異或運算 按位異或運算符“^”是雙目運算符。其功能是參與運算的兩數各對應的二進位相異或,當兩對應的二進位相異時,結果為1。參與運算數仍以補碼出現,
例如:9^5可寫成算式如下:
00001001^00000101 00001100 (十進制為12)
應用:
a.?使特定位的值取反?(mask中特定位置1,其它位為0 s=s^mask)
b.?不引入第三變量,交換兩個變量的值?(設 a=a1,b=b1)
目標操作操作后狀態
a=a1^b1 a=a^b a=a1^b1,b=b1
b=a1^b1^b1 b=a^b a=a1^b1,b=a1
a=b1^a1^a1 a=a^b a=b1,b=a1
4. 求反運算 求反運算符~為單目運算符,具有右結合性。 其功能是對參與運算的數的各二進位按位求反。
例如:~9的運算為:?
~(0000000000001001)結果為:1111111111110110
三、位移運算符
符號 描述
<< 左移
>> 右移
5. 左移運算 左移運算符“<<”是雙目運算符。其功能把“<< ”左邊的運算數的各二進位全部左移若干位,由“<<”右邊的數指定移動的位數,?高位丟棄,低位補0。 其值相當于乘2。
例如: a<<4 指把a的各二進位向左移動4位。
如a=00000011(十進制3),左移4位后為00110000(十進制48)。
6. 右移運算 右移運算符“>>”是雙目運算符。其功能是把“>> ”左邊的運算數的各二進位全部右移若干位,“>>”右邊的數指定移動的位數。其值相當于除2。
例如:設 a=15,a>>2 表示把000001111右移為00000011(十進制3)。
對于左邊移出的空位,如果是正數則空位補0,若為負數,可能補0或補1,這取決于所用的計算機系統。移入0的叫邏輯右移,移入1的叫算術右移,Turbo C采用邏輯右移。
main(){
unsigned a,b;
printf("input a number: ");
scanf("%d",&a);
b=a>>5;
b=b&15;
printf("a=%d b=%d ",a,b);
}
舉例:輸入一個整數,判斷這個數中有幾個二進制位1?例如輸入67,輸出結果應該為3。因為67的相應二進制數為00000000 01000011(0043H),有3個1出現。
分析:要判斷是不是1,只需要判斷該位與1與以后是不是1就可以知道。一個整數,判斷16次即可。
int main(int argc, char *argv[])
{
int num, i, cnt = 0;
scanf("%d", &num);
for(i = 0; i < 16; i++)
{
if(num & 1 == 1) /* 判斷最低位是不是1 */
cnt++;?
num >>= 1; /* num右移1位 */
}
printf("%d\n", cnt);
return 0;
}
這樣每次都判斷最低位是不是1,判斷完以后,讓前面的右移一位即可。 注:文章轉自http://blog.chinaunix.net/uid-26495963-id-3065899.html
總結
- 上一篇: 2021数字化就业新职业新岗位研究报告
- 下一篇: 通宵加班的产品经理,为什么我不建议你买保