当前课程知识点:C语言程序设计(上) > 数据计算实现与顺序结构程序设计(二) > 2.4 位运算的C程序实现 > 2.4.3 位运算怎么用
我们看这个
咱说到了这个位运算
也看到了位运算有
一共现在是有六种位运算的符号
可以用它来构成位运算的表达式
这东西怎么用
或者说它有什么用
我们看一下它怎么用
位运算最大的用处是
比较灵活地处理二进制位
很多我们从网上搜一搜就能看到
很多学C语言的那个用户
都会一提到位运算这
首先是觉得它没有用
其次也是觉得它
它还挺比较不容易去理解
或者弄清楚
最关键的是没有需求牵引
不知道用它做什么
所以会觉得它没有用
其实尤其是对理工类的应用
还是非常广泛的
尤其是它对这个
二进制位的一个直接处理
还是非常有用的
比如说
我们可以用这个按位与
来做什么事情
对我们指定的位数清零
比如说
我们想把一个字节里边
我们说极端
我的最高位和最低位最末位都是1
然后我想把这两位清零
就是一个字节里最高端和最低端
都是1
我现在把它想清零
我怎么清
我就想把这两位清零
我怎么清
大家想想看
你是不是做一个相与的运算
你拿什么去与
你把这两位搁的一定是0
与的这个数的最高位和最末位
放上0
那0与那个1去相与
它不结果就是0了吗
那就把那1变成0了
这就最简单的一个结果
所以我们说
比如说或运算
它容易做什么
把某一位置1
什么叫置1
那个位上本来是0
我让它写上1
比如说我们还说最高位
比如说我这个最高位上本来是0
我现在想让这个最高位上写上1
我怎么做
当然不是与了
一定是或
就是加上一个这个位上是1的
无论你原来那个位上是0还是1
我只要被做或运算的这个位上是1
那个位上必然被签上了1
还有一个是
经常用到的是
取某一位比如说这一个数
我想取它的第五位
和第六位位上的数
其实我不知道这个位上是什么
它也可能是0也可能是1
我想把它取出来
我想把它取出来
大家想想看
我们怎么把它取出来
我就想取第五位
和第六位上的那个数
大家想想
是做或运算还是做与运算
我就可以把它取出来
大家想想这一块一定是做的与运算
我们试着想一想
如果第五位和第六位上是0
我用那两位上我都用1去做
相与的运算
我取出来必然
1和0去相与取出来的是0
如果原来那两位上是1
我做与运算1 1相与
取出来就是1
所以我用做
给我的要取的这个位上签上1
我就可以把原来的那个数据
相应的位上的那个数据
实际的数据取出来
所以取指定位上的数
这里边还有一个
经常的应用
叫做什么
不引用第三个变量
就可以做两数交换
记得我们课程在开始的时候
就给大家拿了两杯果汁
可乐果汁
说这两个杯子交换的时候
我们说了一定要引用第三个变量的
要不然那两个杯子没法直接倒
所以我们用一个中间空杯子
把它倒了一下
两数交换
用三个赋值语句去做它
这里边最主要的一个思路是
借用了第三变量
借用了第三变量
然后把这个倒了一下
位运算就不用了
我们时常有时候会碰到一些
求职的面试
会出这种比较偏一些的题
你要把两个数进行交换
你可以不可以不引用第三个变量
其实这里边就是说
你会不会想到用按位与运算
去实现这个
怎么实现这块
大家想想看
我们刚才说的表达的是这么一个意思
如果a和b要去交换的话
我们通常
在C程序里边是用了tmp
这个中间变量
然后把a先放到这里边
把b再放到a里边
然后最后把tmp里边的临时的
存放的内容再放回b
实现了两数交换
可是按位运算不用这样
按位运算我们看
a b我们在这边
大家看到的都是a b
没有一个数在这里边说
它是一个中间变量
这样的运算做了三次
按位异或运算
实现了两个数交换
大家一定会觉得不明白
实现了吗这个
大家看这个a和b做了异或交换
做了三次异或交换
就不需要中间变量
大家觉得这靠谱吗行吗
我们看一下
然后咱们用红颜色的这个内容
我们说把它放到a里边
绿颜色的内容放在b里边
a和b做异或运算
运算的结果大家看看
是不是产生的是
黑颜色的这个结果
只有相同的一定是0
只有相异的是1
这样的一个结果
相同则0相异是1
得到的这个结果
黑颜色的这个结果放哪
异或的结果放a里边
所以a已经被重新赋值
不是红颜色的了
现在是黑颜色的a
黑颜色的a接下来和谁去运算
和b
b现在是绿颜色的
没有人给它赋值
所以没有变
就是a和b再做异或的运算
a和b做异或运算
同样相同的地方是0
相同的地方是0
三个相同的地方是0
剩下的都是1
三个相同的地方是0
其它的位上按位运算的结果都是1
这是这个黑颜色的结果给了谁了
给了b
新的b产生了
b不是绿颜色的了
是黑颜色的了
这是黑颜色的a这是黑颜色的b
它俩再做一次异或运算
运算的结果同样我们找相同的地方
是1 相同的地方1只有两处
只有这两个位上
结果是0剩下的全是1
是红颜色的这个结果
这个结果赋值给谁
赋值给a
赋值给了a
是这样红颜色的结果
我们现在看这是最终的结果
我们现在要找红颜色的a
和绿颜色的b交换了吗
我们一定现在说
这个a里边的红颜色
一定和原来的b里的绿颜色是一样的
它就交换了
这个a和b没有问题了
就是把a原来的b里的内容已经放在
现在的a里边了
原来这个
现在新的b里的内容
是不是原来a里边的
这个黑颜色的
OK没问题 实现了交换
也就说三次异或按位异或
实现了两数交换
通常大家实际上在这个程序设计里边
多数人不这样用的
多数人都还是喜欢这样用
两数交换这样用
那是为什么
有没有说它更简单
它更麻烦 没有
只是大家不习惯用这个按位运算
实际上
我们现在在刚才举的这个例子里边
大家看上去是说
我用这种借用一个中间变量做
可读性又好
使大家看起来非常明了
也浪费一个内存变量
计算机是不计较的
所以大家习惯都用这个
但是有些地方
没有位运算你是实现不了这个功能
比如说
我们刚才说
把某些个别二进制位清零
把某些位置1
取某些位的二进制位数
尤其是我们一些比如说加幂
一些比如说奇偶的一个校验
把一些数让它变成偶数
变成奇数 奇数变成偶数
这样只能通过位运算来进行
尤其是一些什么样的专业
比如说机械类的
自动控制类的
位运算用的还是比较多的
比如说我们下面再给一个例子
我们用二进制取位操作
比如说and1
这就是我们刚才说的and 1的结果
就是取二进制位的
最高位还是最末位
and1前面全是0后边是1
就是取1个数的最末位
当然我们用and1个数的方法
可以取出来
一个二进制位里边的任何一位
or呢 一样
or一个1的结果
就是把二进制位的最末位
强行变成1
无论你原来是0还是1
我只要给你按位或一个1
那一定把你强行变成1了
就像下边的我们现在这样说的
你每一位上就别碰着了
强行把你变成1了
我们举这两个例子实际上主要是为了
给大家说位运算的作用
但是在我们这门课程里边
大家现在用的过程里边
位运算的确用的还是比较少的
我们最后再给大家一个程序
看一下我们刚才说的
三次异或完成了
两数交换的这么一个功能
我们现在给的数
是为了方便大家看给得再小一些
a里边放的是9
b里边放的是7
我们这给了大家一个注释
比如说a里边是1001是9
实际上我们是int a
int a应该是两个字节
两个字节那就说前面它还有12位
都有数的
应该那些数是0
正的前面是0
所以我们是0的部分就没有写出来
我们只写有效数字的部分
1001
b里边是7那就是0111
把这两个a和b要进行交换的话
做了三次运算
大家分析一下这有注释
大家试着把这个程序
下去自己调试一下看看
然后也可以你自己换一个数据
然后看一下自己再写一下
像这两个交换的过程
应该实现的是一个什么样的功能
以及它的过程里边的变化是什么样的
这一块我们就到这
-1.1 计算机的问题求解方法
--讨论题:数学模型
-1.1 计算机的问题求解方法--作业
-1.2 C语言与C程序
--讨论题:运算符
-1.3 C语言处理系统与程序调试运行
--例程
-1.4 程序中的人机交互
--例程
--作业讨论区
-2.1 算术运算的C程序实现
--算术混合运算.c
-2.1 算术运算的C程序实现--作业
-2.2 关系运算的C程序实现
--bukao.c
--字符比较.c
--讨论题:比较大小
-2.2 关系运算的C程序实现--作业
-第二周作业--作业
-2.3 逻辑运算的C程序实现
--计算结合性
--闰年.c
--自动购票问题.c
-2.3 逻辑运算的C程序实现--作业
-2.4 位运算的C程序实现
--讨论题:位运算
-2.5 几种很个别的运算
--讨论题
--讨论题
-2.5 几种很个别的运算--作业
-2.6 混合运算及数据类型转换
--讨论题:数据类型
-2.7 顺序结构程序实例
--Video
--三角形面积.c
--讨论题:工业产值
-2.7 顺序结构程序实例--作业
-3.1 程序中的路径选择实现
--打印学生成绩.c
--一元二次方程.c
-3.1 程序中的路径选择实现--作业
-3.2 路径中的再选择——嵌套判断
--例程
--讨论题:程序改错
-3.2 路径中的再选择——嵌套判断--作业
-3.3 复杂判断问题的C程序设计
--3.3 多级选择
--银行存款.c
--讨论题:多级选择
-3.4 多分支问题的C程序设计
--加减乘除运算.c
-3.4 多分支问题的C程序设计--作业
-3.5 GOTO的适当使用
-3.6 选择结构的程序实例
--3.6 程序展示
--计算第几天.c
--讨论题:输出奇数
--讨论题:计算税金
-3.6 选择结构的程序实例--作业
-第四周作业--作业
-4.1 需要重复执行的程序
--求和.c
--打印学生成绩.c
--统计录入速度.c
--求平均数.c
-4.1 需要重复执行的程序--作业
-4.2 至少要执行一次的循环
--n的阶乘.c
--字符分类统计.c
-4.2 至少要执行一次的循环--作业
-4.3 已知循环次数用for语句
--求和问题.c
--数列求和.c
--讨论题:循环语句
-4.3 已知循环次数用for语句--作业
-4.4 循环控制——简单循环应用
--水仙花数.c
--讨论题:死循环
--讨论题:猜数字
-循环结构的程序设计(一)--4.4 循环控制——简单循环应用
-4.5 循环的嵌套
--讨论题:程序运行
-4.5 循环的嵌套--作业
-4.6 break与continue
--最大素数.c
-4.6 break与continue--作业
-4.7 循环的综合应用
--数的排列组合.c
--鸡兔同笼.c
--打印空心字符.c
--讨论题:打印图形
--讨论题:计算闰年
-第六周作业
-第六周作业--作业
-5.1 同类有序数据处理问题
-5.2 一维数组的定义和引用
--数组定义.c
--数组初始化.c
--反向输出.c
--讨论题:对称数
-5.2 一维数组的定义和引用--作业
-5.3 一维字符串数组
--讨论题:编程
-5.4 字符串处理函数
--字符串反向.c
--字符串函数
-5.5 二维数组的定义与使用
-5.6 二维数组的输入输出
-5.6 二维数组的输入输出--作业
-5.7 二维数组的应用
--转置矩阵.c
--讨论题:修改程序
-5.8 二维字符数组
--5.8 单词排序
--单词排序.c
-5.8 二维字符数组--作业
-5.9 数组综合应用
--统计成绩.c
--统计字符次数.c
--讨论题:洗牌
-本期课程结束语
--end
-第八周编程作业
-《C语言程序设计(上)》期末复习参考
--html
-《C语言程序设计(上)》期末复习参考答案
--html