位操作符这么玩是吧?好好好

& //按位与
| //按位或
^ //按位异或
注:他们的操作数必须是整数。
⼀道变态的⾯试题:
不能创建临时变量(第三个变量),实现两个数的交换。

正常情况下交换两个数的大小我们需要创建第三个变量

#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 &lt;&lt; 4); 这一行的目的是将 a 的二进制表示中的第五位(从右边开始数,从0开始计数)设置为1。具体过程如下:
5.1 &lt;&lt; 4 将1左移4位,得到二进制 00000000000000000000000000010000。
6.a | (1 &lt;&lt; 4) 将 a 的二进制表示和上述结果进行按位或操作,将第五位设置为1。
7.结果为 00000000000000000000000000011101,即十进制的29。
8.printf("%d\n", a); 打印修改后的 a 的值。


9.将第五位改为0:


10.a = a &amp; ~(1 &lt;&lt; 4); 这一行的目的是将 a 的二进制表示中的第五位设置为0。具体过程如下:
11.1 &lt;&lt; 4 将1左移4位,得到二进制 00000000000000000000000000010000。
12.~(1 &lt;&lt; 4) 对上述结果取反,得到 11111111111111111111111111101111。
13.a &amp; ~(1 &lt;&lt; 4) 将 a 的二进制表示和上述结果进行按位与操作,将第五位设置为0。
14.结果为 00000000000000000000000000001101,即十进制的13。
15.printf("%d\n", a); 打印修改后的 a 的值。

通过这种方式,可以方便地设置或清除整数变量中的特定位。这是位运算在底层硬件操作和一些优化算法中的常见应用。

希望大家能够看懂

不懂的后台dd噢~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值