C语言按位操作符
目录
基本介绍
在c语言中按位操作符有四种 “&“ “|“ “^“ “~“
- 按位与“&“
仅当两个操作数为1时,结果才为1
Eg: 0&0=0; 0&1=0; 1&1=1;
- 按位或“|“
两个操作数中至少有一个1时,结果就为1
Eg:0&0=0; 0&1=1; 1&1=1;
- 异或“^“
两个操作数不相同时,结果为1
Eg:0&0=0; 0&1=1; 1&1=0;
可以看出操作数与0异或结果为其本身。
操作数与其本身异或为0
- 取反“~“
将0置为1,1置为0.
Eg: 0~ =1; 1~=0;
附加几个:
移位操作符:
>>向右移位,左边补0
Eg: 10的二进制为0000 1010
10>>1 = 0000 0101
<<向左移位,右边补0
Eg: 10的二进制为0000 1010
10<<1 = 0001 0100
应用
- 将两个数a与b交换位置,要求不创建第三个变量
Int a=10; int b=20;
答:
a=a^b;
b=a^b; //意思为: a^b^b 其中b^b=0,a^0=a;故b=10,即a的值
a=a^b; //意思为: a^b^a。
2. 统计一个数的二进制中的1的个数:
Eg: 10 的二进制为0000 1010 其中1的个数为1
答:使用移位操作符。让右边的第一位与0000 0001进行按位与&操作
刚开始:0000 1010 & 0000 0001=0
向右移动一位>>再与0000 0001进行&操作 0000 0101 & 0000 0001=1
向右移动一位>>再与0000 0001进行&操作 0000 0010 & 0000 0001=0
向右移动一位>>再与0000 0001进行&操作 0000 0001 & 0000 0001=1
向右移动一位>>再与0000 0001进行&操作 0000 0000 & 0000 0001=0
到0000 0000时,停止
判断结果是否为1,如果为1,则说明二进制里面有个1,将其进行累加
完整程序实例:
int a=10;
int number=0;
while(a>0){
a=a>>1;
number=number+(a&0x01);//这里的括号是更改优先级
}
3.将一个整数的二进制的奇数和偶数互换位置
eg: 10
再看10之前,我们先来个简单的:
00001111 思路:将偶数位右移一位 奇数位左移一位
奇数位 00000101 00001010
偶数位 00001010 00000101
最后再将奇数位 +00001111
和偶数位合并 .
可以看出问题的关键时如何分离出整数的奇数位和偶数位
不妨考虑一下0xaaaaaa与0x555555
十六进制a的二进制位1010
5的二进制位0101
1010 1010
& 0000 1010
= 0000 1010 --偶数位
1111 1111
& 0000 0101
= 0000 0101 –奇数位
再结合上面的偶数位右移,奇数位左移,结果相加即可。
在这里为啥要使用0xaa 与0x55
因为这两个十六进制的二进制分别为1010与0101,正好可以通过&符号分离出来
有了以上的例子,再来看10
00000000 00000000 00000000 00001010
& 10101010 10101010 10101010 10101010
= 00000000 00000000 00000000 00001010 -偶数位
00000000 00000000 00000000 00000101 -偶数位右移
00000000 00000000 00000000 00001010
& 01010101 01010101 01010101 01010101
= 00000000 00000000 00000000 00000000-奇数位
00000000 00000000 00000000 00000000 -奇数位左移
00000000 00000000 00000000 00000101 -偶数位右移后的值
+ 00000000 00000000 00000000 00000000 -奇数位左移后的值
= 00000000 00000000 00000000 00000101
完整代码:
void funtionc() {
int val = 10;
int ret = ((val & 0xaaaaaaaa) >> 1) + ((val & 0x55555555) << 1);
printf("%d ",ret);
}