位操作符

位操作符有三种,即:
①按位与----- &
②按位或----- |
③按位异或-- ^
还有一类操作符叫逻辑操作符,分别为:
①逻辑与----- &&
②逻辑或----- ||
千万不能与按位与(&)和按位或(|)搞混

按位与(&)

int a=5,b=3;
printf("%d\n",a&b);

由于int是4字节,所以a与b的值的二进制分别为

5:00000000 00000000 00000000 00000101
3:00000000 00000000 00000000 00000011

按位与(&)的计算方式为:同为1,方为1
也就是说只有两个位都是1的时候才能是1
即a与b进行按位与运算后输出为

00000000 00000000 00000000 00000001

即为1

按位或(|)

a=5;
b=3;
printf("%d\n",a|b);

此时对ab进行或运算
按位或(|)运算的方式为:遇1则为1
即只要有1 便是1,ab的值的二进制为:

00000000 00000000 00000000 00000101
00000000 00000000 00000000 00000011

运算后为

00000000 00000000 00000000 00000111

即为7

按位异或(^)

a=5;
b=3;
printf("%d\n",a^b);

按位异或(^)的运算方式为:相异为1,相同为0

00000000 00000000 00000000 00000101
00000000 00000000 00000000 00000011

单独提出
101
011
此时前两个位都是相异,第三位为相同,即输出为

00000000 00000000 00000000 00000110

即为6

按位运算的目的:操控位

例:如何将3的第一位控制为0?

int a=3,b=1;
printf("%d\n",a^b);

3的二进制为

00000000 00000000 00000000 00000011

此时要将第一位变成0,即要将3变成

00000000 00000000 00000000 00000010

要想变化,只需让3与1异或,即

00000000 00000000 00000000 00000011

00000000 00000000 00000000 00000001


00000000 00000000 00000000 00000010

现在不想让第一位变化了,我想让第八位变化,此时需要用到移位的方式,即

a=3;
b=1;
printf("%d\n",a|b<<7);

即让a|b向左位移七位
b=1

00000000 00000000 00000000 00000001

向左位移七位

00000000 00000000 00000000 10000000

此时与a按位或

00000000 00000000 00000000 00000011

00000000 00000000 00000000 10000000


00000000 00000000 00000000 10000011

同样用异或也能解决下面的问题
有一数组c=[3,1,3,2,2],只有一个数只出现了一次,其他的数都出现了两次,请找出出现了一次的数

int c=[3,1,3,2,2];
int i=0;
int ret=0;\\防止数组中只有一个数
while(i<5)
{ret=ret^a[i];i+=1;
}
return 0;

这串代码中,开始ret=0,即为

00000000 00000000 00000000 00000000

此时进入程序,i=0<5,执行while循环

ret^a[0]

00000000 00000000 00000000 00000000

^00000000 00000000 00000000 00000011


ret==00000000 00000000 00000000 00000011 == 3

i=1

ret^a[1]

00000000 00000000 00000000 00000011

^00000000 00000000 00000000 00000001


ret==00000000 00000000 00000000 00000010 ==2

i=2

ret^a[2]

00000000 00000000 00000000 00000010

^00000000 00000000 00000000 00000011


ret==00000000 00000000 00000000 00000001 ==1

i=3

ret^a[3]

00000000 00000000 00000000 00000001

^00000000 00000000 00000000 00000010


ret==00000000 00000000 00000000 00000011 ==3

i=4

ret^a[4]

00000000 00000000 00000000 00000011

^00000000 00000000 00000000 00000010


ret==00000000 00000000 00000000 00000001 ==1

i=5,循环结束,输出为1,也就是数组中单独的数


12.14日更新

如果需要将两个数进行交换,应该怎么做?

想起以前有一个小游戏,一个人要带一只狼一只羊和一捆菜过河,但是船太小了,一次只能送一种东西到对岸去,但是狼和羊在一起时狼会吃羊,羊和菜在一起时羊会吃菜,那么应该怎么办呢?

刚看到这个问题的时候好像还是小学,当时是冥思苦想,不知道该咋办,虽然最大的关注点还是为什么带着狼一块走不会被吃掉,现在想想那狼怕不是是个二哈

言归正传,狼羊菜过河,怎么过?
第一趟:把羊带过去
第二趟:把菜带过去,随后把羊带回来
第三趟:把狼带过去
最后一趟:把羊带过去
即始终要保持狼和菜在同一边并且不能让狼与羊或羊与菜共处

那么回到问题来,想让两个数的位置互换

int main()
{int a = 10,b = 20;return 0;
}

现在有两个数a,b,怎么让他们互换呢
再举个通俗易懂的例子,有两杯水,怎么互换?
很简单,再拿个杯子过来,一杯倒进去,第二杯倒进第一杯,再把原先第一杯的水倒进第二杯,即:

int main()
{int a = 10,b = 20;int c;c = a;a = b;b = c;return 0;
}

是不是跟水倒来倒去很像,改进一下

#include <stdio.h>
#include <stdlib.h>int main()
{int a = 20, b = 10;printf("a = %d, b = %d\n", a, b);int c;c = a;a = b;b = c;printf("a = %d, b = %d\n", a, b);system("pause");return 0;
}

输出看看结果

这样是不是就换成功了
但是这跟位操作符又有什么关系呢?
莫急嘛,马上就来了
如果这个时候我定个条件,你不能多拿个杯子,也就是不能增加变量,你怎么倒?

脑洞一下
把两杯水放进冰箱里边,把它们冻成冰,再进行交换
这也是个好办法,改变他们的形态。但是在c语言里我们应该怎么办呢

此时就需要利用到异或的知识了
前面有提到过,按位异或时相同为 0 相异为 1 ,即两个相同的数在进行异或时会变成 0

这时候就得有大胆的想法了

#include <stdio.h>
#include <stdlib.h>int main()
{int a = 20, b = 10;printf("a = %d, b = %d\n", a, b);a = a^b;b = a^b;a = a^b;printf("a = %d, b = %d\n", a, b);system("pause");return 0;
}


完成,然后就发现自己开始不懂了,这啥玩意,咋就完成了
其实挺好理解的,首先我们需要记住两个相同会抵消
第一步 a = a ^ b

到了第二步 b = a ^ b
此时将 a = a ^ b 代入,即为 b = a ^ b ^ b
两个 b 相消,即 b = a

再到第三步 a = a ^ b
此时在第一步中 a = a ^ b,即 a = a ^ b ^ a
两个 a 相消,即 a = b
完成转换

位操作符:与,或,异或 狼羊菜相关推荐

  1. 农夫过河狼羊白菜Java开放封闭_农夫过河——狼羊菜问题

    话说一位农夫带着一只狼.一只羊和一个卷心菜过河,无奈船小,农夫每次只能运送一样东西,考虑到狼吃羊.羊吃菜,因此运送的顺序至关重要. 在现实世界里解决这个问题并不困难,相信很多人都已经有了答案,但是如何 ...

  2. 狼羊菜问题的算法思想和C++实现(二进制状态表示 递归状态转移 回溯 剪枝)

    狼羊菜问题的算法思想和C++实现 狼羊菜问题 把[狼.羊和蔬菜]这三样东西安全地送至河的对面,你能用的工具只有身边的一艘小船.已知,这艘小船很小,当你坐在里面时,其只能搭载[狼.羊和蔬菜]这三样东西中 ...

  3. 狼羊菜过河问题深入学习分析——Java语言描述版

    前言 这个问题的抛出,是几个星期之前的算法课程.老师分析了半天,最后的结论是:其实就是图的遍历.那时候挺懵逼的,不管是对于图,还是遍历,或者是数据结构,心里面都没有一个十足的概念,所以搁置了这么久的问 ...

  4. 算法之狼羊菜过河问题

    算法之狼羊菜过河问题 1.带羊再带狼 回来时把羊带上 然后把白菜带到对岸 最后把羊带过去 2..带羊再带菜 回来时把羊带上 然后把狼带到对岸 最后把羊带过去 关键点在于羊和两个都有联系,而狼不吃菜,

  5. 狼羊菜过河(C实现)

            题目描述:农夫需要把狼.羊.菜和自己运到河对岸去,只有农夫能够划船,而且船比较小,除农夫之外每次只能运一种东西,还有一个棘手问题,就是如果没有农夫看着,羊会偷吃菜,狼会吃羊.请考虑一种 ...

  6. *python解决狼羊菜过河问题

    python解决狼羊菜过河问题 A岸有菜,羊,狼,农夫农夫必须将他们都送到B岸每次只能送一个,在保证他们不会被吃的前提下,完成任务,并得出步骤. 代码: A=[["狼",1],[& ...

  7. java狼羊草过河_狼羊菜过河问题深入学习分析——Java语言描述版

    前言 这个问题的抛出,是几个星期之前的算法课程.老师分析了半天,最后的结论是:其实就是图的遍历.那时候挺懵逼的,不管是对于图,还是遍历,或者是数据结构,心里面都没有一个十足的概念,所以搁置了这么久的问 ...

  8. 狼羊菜过河问题c语言算法,算法系列之十四:狼、羊、菜和农夫过河问题

    题目描述:农夫需要把狼.羊.菜和自己运到河对岸去,只有农夫能够划船,而且船比较小,除农夫之外每次只能运一种东西,还有一个棘手问题,就是如果没有农夫看着,羊会偷吃菜,狼会吃羊.请考虑一种方法,让农夫能够 ...

  9. java狼羊草过河_狼羊菜过河

    思路:用0/1代表所处位置,农夫.狼.羊.菜过河就是0000->1111,一共是16种状态,去掉其中的不可能的状态如0011(羊和菜单独一起)是10种. 可以用图的方式表示: 或者用树的方式表示 ...

最新文章

  1. 如何彻底卸载mysql(xp)
  2. 实体识别+entity resolution
  3. Avdshare Audio Converter 7中文版
  4. .NET开发中应该遵循的几点建议
  5. Javascript 之 变量
  6. 用css控制背景图片的位置,大小
  7. matlab二元一次方程求解_方程的计算机处理913_Matlab
  8. 用U盘PE启动安装系统教程
  9. win10本地计算机策略进不去,win10系统gpedit.msc打不开怎么处理 win10本地安全策略打不开...
  10. 外卖优惠券小程序源码,美团外卖,饿了么外卖红包
  11. 【大黄蜂打印机cura切片软件配置】
  12. 安卓手机APP读写高频RFID标签(校园卡)NDEF格式数据设计
  13. WeBRTC IOS视频采集流程
  14. 打印机服务器文件,打印机服务器ftp配置文件
  15. LDO线性稳压电源PCB布局布线
  16. 用友YonSuite释放商业创新的“蝴蝶效应”
  17. win10 启动vmware虚拟机就会蓝屏解决方法
  18. python自动化(三)web自动化:2.web自动化工具selenium讲解
  19. wden小波滤波函数
  20. 2020年下半年系统集成项目管理工程师下午真题及答案

热门文章

  1. selenium使用webdriver新开标签页
  2. mysql主从有关参数_mysql主从复制配置
  3. Git--生成公钥和私钥并添加gitlab访问权限
  4. python接口自动化测试六:时间戳,防重复处理
  5. 微信小程序开发-微信登陆流程
  6. 最小生成树基础 (Kruskal)
  7. iOS开发日记46-倒计时效果的实现
  8. 自定义 Javascript 模板规则,打造轻量级模板引擎
  9. pygtk在windows的安装
  10. 黄冈中学首页布局(自己做的)