前言:
C语言的位运算有6种:按位与& 、按位或| 、按位取反~ 、按位异或^ 、按位左移<< 、按位右移>>
注意:能够参与位运算的操作数 必须是整型 ,以补码形式 进行按位运算
(一)按位与& (双目运算符)
0 | 1 ? 0 1 | 0 ? 0 1 | 1 ? 1 0 | 0 ? 0
(1)迅速清零
#include <stdio.h>
int main()
{
int a = 15;
a = a & 0;
printf("a = %d\n", a);
return 0;
}
结果:
从这还不足以看出按位与&的真正魅力,主要做作用就在下面
(2)保留指定位
#include <stdio.h>
int main()
{
int a = 15;
a = a & 6;
printf("a = %d\n", a);
return 0;
}
(3)判断奇偶性
补码的最低位是0,就是偶数,1是奇数
所以使用任意数和1进行按位与,即(num & 1) == 0 ? 偶数 : 奇数
注意:逻辑运算符的优先级高是7,按位运算符的优先级低是9
我们来输出下[1 - 100] 之间的偶数
#include <stdio.h>
int main()
{
for (int i = 1; i <= 100; i++)
{
if ((i & 1) == 0)
{
printf("%-4d", i);
}
}
return 0;
}
拓展: 按位与&不光能判断奇偶性,而且还能判断能够被2^n (n>=0)整除的数 总结:
- 判断一个数num能否被
2^n 整除,使用(num & (2^n - 1))) == 0 ? 偶数 : 奇数 - 例如:一个整数内否被4整除
#include <stdio.h>
int main()
{
for (int i = 1; i <= 100; i++)
{
if ((i & 3) == 0)
{
printf("%-4d", i);
}
}
return 0;
}
(二)按位或 | (双目运算符)
0 | 1 ? 1 1 | 0 ? 1 1 | 1 ? 1 0 | 0 ? 0
(1)修改数据的指定位的值
例:把char类型的十进制100的第4个二进制位改成1 把100 : 1100 0100 使用 | : 0000 1000 结果: 1100 1100(108)
#include <stdio.h>
int main()
{
char a = 100;
a = a | 0x08;
return 0;
}
(三)按位取反~(单目运算符)
~0 ? 1 ~1 ? 0
(1)方便表示一个数字,通常和& | 结合使用
#include <stdio.h>
int main()
{
int a = 0x12345678;
int b = a & 0xffffff00;
printf("b = %x\n", b);
b = a & ~255;
printf("b = %x\n", b);
return 0;
}
(四)按位异或^(双目运算符)
0 ^ 0 ? 0 0 ^ 1 ? 1 1 ^ 0 ? 1 1 ^ 1 ? 0
(1)按位异或的规律
- 结合律:a ^ (b ^ c) == (a ^ b)^ c
- 交换律:a ^ b == b ^ a
- 归零律:a ^ a == 0
- 恒等率:a ^ 0 == a
- 自反性:a ^ b ^ a == b
(2)判断两个数是否相等
(3)交换两个数
#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;
}
(4)一个整型数组里的value只出现了一次,其余数据都是两次,请找到这个数
int main()
{
int arr[] = {2, 1, 5, 4, 2, 1, 6, 5, 6};
int len = sizeof(arr) / sizeof(arr[0]);
int ret = 0;
for (int i = 0; i < len; i++)
{
ret = ret ^ arr[i];
}
printf("%d\n", ret);
return 0;
}
(四)按位左移<<,按位右移>>
<<左移:最低位填充0
>>右移:
练习题:计算一个整型数对应的二进制数中1的个数
(1)解法一
#include <stdio.h>
int GetOneNum(int num)
{
int bit_num = sizeof(num) * 8;
int count = 0;
while (bit_num--)
{
if ((num & 1) == 1)
{
count++;
}
num >>= 1;
}
return count;
}
int main()
{
int test = 0xd2;
printf("number of 1 : %d\n", GetOneNum(test));
return 0;
}
(2)解法二
int GetOneNum(unsigned int num)
{
int count = 0;
while (num != 0)
{
if ((num & 1) == 1)
{
count++;
}
num >>= 1;
}
return count;
}
(3)解法三
int GetOneNum(int num)
{
int count = 0;
while (num != 0)
{
num = num & (num - 1);
count++;
}
return count;
}
(4)解法四:查表法
int GetOneNum(int num)
{
int num_4bit = sizeof(num) * 2;
int count = 0;
while (num_4bit--)
{
count = count + "0112122312232334"[num & 0x0f] - '0';
num >>= 4;
}
return count;
}
|