& //按位与
| //按位或
^ //按位异或
注:他们的操作数必须是整数。
⼀道变态的⾯试题:
不能创建临时变量(第三个变量),实现两个数的交换。
正常情况下交换两个数的大小我们需要创建第三个变量
#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",a,b);
return 0;
}
首先感受一下
开始
按位与&
它的运算标准为有0则为0
同时为1才为1
切记,运算的时候这些数都是要转化为二进制数再进行位操作的
按位或|
它的运算标准为
有1则为1
同时为0才为0
是不是和平时判断差不多
最后重磅嘉宾
按位异或^
它的运算标准为
相同则为0
相异则为1
3^5^3=5
3^3^5=5
所以异或是有交换律的
但异或操作有局限性
1.只能用作整数交换
2.代码的可读性差
3.代码执行的效率也是低于第三变量的方法
上面的代码
a=a^b;
b=a^b;//这里仔细分析一下是不是就是b=a^b^b 所以b=a了
a=a^b;//这里是不是就是a=a^b^a相当于a=a^a^b 所以a=b
当然实现不用第三个变量实现两数交换也有别的方法
a=a+b;
b=a-b;
a=a-b;
计算补码中有多少个1
方法1
int main()
{
int a=0;
scanf("%d",&a);
int i=0;
int count=0;
for(i=0;i<32;i++)//因为内存中存储为32个bit
{
if(((a>>i)&1)==1)//运用按位与 注意!这里的1在内存中为补码存储
{
count++;
}
}
printf("%d",count);
return 0;
}
方法2
int main()
{
int n=0;
scanf("%d",&n);
int count=0;
while(n)
{
n=n&(n-1);//这一行是一个经典的技巧,用于去掉 n 二进制表示中最右边的一个1。这是因为 n-1 将把最右边的1及其右边的0变成0,而将最右边的1左边的位不变,然后与 n 进行按位与操作,相当于将最右边的1变成了0。
count++;
}
printf("%d",count);
return 0;
}
写一个代码,判断一个数是否为2^n次方
2^n这个数的二进制中只有一个1
int main()
{
int n=0;
scanf("%d",&n);
if((n&(n-1))==0)
{
printf("yes");
}
else
printf("no");
return 0;
}
(n & (n-1)) == 0
这是判断n
是否是2的幂的条件。这个条件的原理是,如果n
是2的幂,那么它的二进制表示中只有一个1,而(n-1)
的二进制表示中全部是1,因此它们的按位与操作结果应该为0。如果(n & (n-1))
的结果为0,就说明n
是2的幂。
int main()
{
int a=13;
//00000000000000000000000000001101
//00000000000000000000000000010000
//1<<4
//将a的二进制中第五个改为1
a=a|(1<<4)
printf("%d\n",a);
//将a的第五位改为0
//00000000000000000000000000011101
//11111111111111111111111111101111
//00000000000000000000000000001101
a=a&~(1<<4);
printf("%d\n",a);
return 0;
}
这段代码演示了如何使用位运算来设置或清除整数变量中的特定位。让我们逐步解释:
1.初始值:
2.int a = 13; 初始化整数变量 a 为13,其二进制表示为 00000000000000000000000000001101。
3.将第五位改为1:
4.a = a | (1 << 4); 这一行的目的是将 a 的二进制表示中的第五位(从右边开始数,从0开始计数)设置为1。具体过程如下:
5.1 << 4 将1左移4位,得到二进制 00000000000000000000000000010000。
6.a | (1 << 4) 将 a 的二进制表示和上述结果进行按位或操作,将第五位设置为1。
7.结果为 00000000000000000000000000011101,即十进制的29。
8.printf("%d\n", a); 打印修改后的 a 的值。
9.将第五位改为0:
10.a = a & ~(1 << 4); 这一行的目的是将 a 的二进制表示中的第五位设置为0。具体过程如下:
11.1 << 4 将1左移4位,得到二进制 00000000000000000000000000010000。
12.~(1 << 4) 对上述结果取反,得到 11111111111111111111111111101111。
13.a & ~(1 << 4) 将 a 的二进制表示和上述结果进行按位与操作,将第五位设置为0。
14.结果为 00000000000000000000000000001101,即十进制的13。
15.printf("%d\n", a); 打印修改后的 a 的值。
通过这种方式,可以方便地设置或清除整数变量中的特定位。这是位运算在底层硬件操作和一些优化算法中的常见应用。
希望大家能够看懂
不懂的后台dd噢~