位操作运算
& 按位与、| 按位或 、^ 按位异或、<< 左移、>> 右移
1、& 按位与
将两个数的二进制数相应的位进行与运算,则遵循有0得0,全1得1的原则。(有0为0)
如:
int main()
{
int a = 0;
a = 4 & 7;//100^111=100
printf("%d\n", a);//4
return 0;
}
2、| 按位或
将两个数的二进制数相应的位进行或运算,则遵循有1得1,全0得0的原则。(有1为1)
如:
int main()
{
int a = 0;
a = 3 | 6;//011|110=111
printf("%d\n", a);//7
return 0;
}
3、^ 按位异或
将两个数的二进制数相应的位按位异或运算,则遵循相同得0,不同得1的原则。
如:
int main()
{
int a = 0;
a = 3 ^ 6;//011^110=101
printf("%d\n", a);//5
return 0;;
}
4、<< 左移
左移操作符 移位规则:左边抛弃、右边补0
如:
int main()
{
int num = 3;
num=num << 2;//00000000 00000000 0000000 00000011<<2=00000000 00000000 00000000 00001100
printf("%d\n", num);//12
return 0;
}
5、>> 右移 (同理)
右移操作符 移位规则:
首先右移运算分两种:
- 逻辑移位 左边用0填充,右边丢弃
- 算术移位 左边用原该值的符号位填充,右边丢弃
如:
1.
int main()
{
int num = 5;
num=num >> 2;//00000000 00000000 0000000 00000110>>2=00000000 00000000 00000000 00000001
printf("%d\n", num);//1
return 0;
}
2.
int main()
{
long int num = -8;
num=num >> 1;//10000000 00000000 0000000 00001000>>1=10000000 00000000 00000000 00000100
printf("%d\n", num);//-4
return 0;
}
应用
1.一组数据中只有一个数字出现了一次,其他的数字都成对出现,请找出这个数。
分析:找出一组数据中单独出现的数,就要将数组中的所有数进行异或运算。(相同的数异或为0)
#include<stdio.h>
int main()
{
int arr[] = { 1, 3, 3, 1, 4, 6, 4, 5, 5};
int i = 0;
int result = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
result ^= arr[i];
}
printf("%d\n", result);
return 0;
}
2.不使用(a+b)/2这种方式,求两个数的平均数
分析:将两个数的二进制形式右移一位相当于该数除以二。
#include<stdio.h>
int main()
{
int a = 7;
int b = 9;
int result = 0;
result = (a + b) >> 1;
printf("%d\n", result);
return 0;
}
3.不使用临时变量交换两个数的值。
分析:一个数和另一个数异或两次得到的还是原来的数
#include<stdio.h>
int main()
{
int a = 7;
int b = 8;
a = a^b;
b = a^b;
a = a^b;
printf("%d %d\n", a, b);
return 0;
}
4.统计一个整数中二进制位上1的个数。
分析:n&(n-1)将整数n的最后一位为1的位变成0.
#include<stdio.h>
int main()
{
int a = 11;//1011
int count = 0;
while (a)
{
a = a&(a - 1);
count++;
}
printf("%d\n", count);
return 0;
}