位运算符 | 含义 |
---|---|
& | 按位与 |
| | 按位或 |
^ | 按位异或 |
~ | 取反 |
<< | 左移 |
>> | 右移 |
位运算符中除了~,其他均为二元运算符,需要两个操作数;
操作数可以是整型和字符型,单数不能为浮点型;
按位与:
有假即假
0&0=0 0&1=0
1&0=0 1&1=1
按位或:
有真即真
0|0=0 0|1=1
1|0=1 1|1=1
按位异或:(xor)
同假异真
0^0=1 1^1=1
1^0=0 0^1=0
异或运算符的作用:
1、使特定位翻转:使高四位不变,低四位取反;如下图,使01110110,
使用00001111与其异或就能达到目的;与0异或不变,与1异或取反;
交换两个数的值,不用临时变量:
a=6;b=7;
要交换这两个数的值可以不适用临时变量,用异或运算就可以完成;
a=a^b;
b=b^a;
a=a^b;
就完成了两个数值得交换;
按位取反:
每一位按位取反,即0变为1,1变为0;
左右移运算符:
左移运算符是讲一个数的每一个二进制位向左移;
如:a=15;
a<<2;(表示a左移两位)
a=15的二进制原本为:00001111;
左移两位以后为:00111100;(60)
所以左移一位就等于原来的数乘2,左移两位就乘4;(只适用于左移溢出舍弃的高位中不含1的情况);
左移的时候高位溢出舍去,低位补零;
右移的时候低位溢出舍去,对于无符号整数,高位补零;
右移一位除以2,右移n位,除以2的n次方;
对于有符号整数来说,正数右移,高位依然补0。负数右移,高位保持为1。而对于有符号数来说,进行逻辑右移。z在C语言中,无符号数依然可以为负数;
移入0的称为逻辑右移,即简单右移;移入1的称为算数右移;
下面来讲讲逻辑右移和算数右移:
上面说了,对于无符号数来说,右移高位补0;可能大家都知道无符号数只有正数。但是在c语言中,负数也可以声明为无符号数,此时右移,高位依然补0;
#include<stdio.h>
int main()
{
unsigned char a=-2;
a=a>>1;
printf("%d",a);
return 0;
}
-2的二进制表示为11111110,因为声明为无符号数,所以右移一位以后高位补零(逻辑右移)01111111最后结果为127;
如果将其声明为有符号数,那么根据规则,-2的最高位为符号位1,按位右移的话进行算数右移
#include<stdio.h>
int main()
{
char a=-2;
a=a>>1;
printf("%d",a);
return 0;
}
-2的二进制为11111110,进行算数右移以后为11111111(-1);
对于有符号数中的正数来说依然进行逻辑右移;
最后总结一下,负数进行算数右移,正数进行逻辑位移。但是负数被声明为无符号类型时,进行逻辑右移;也就是负数既可以进行逻辑右移,也可以进行算数右移,但是正数只能进行逻辑右移。