《第十一章位运算.ppt》由会员分享,可在线阅读,更多相关《第十一章位运算.ppt(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第十一章第十一章 位运算位运算一、一、位运算的概念位运算的概念二、二、位运算符位运算符三、三、位运算的常用用法位运算的常用用法四、四、位运算复合赋值运算符位运算复合赋值运算符五、五、位段位段 前面所学习的所有运算都是对某个变量所进行的操作,其实前面所学习的所有运算都是对某个变量所进行的操作,其实C语言还可以对变语言还可以对变量中的个别位进行操作。尤其是使用量中的个别位进行操作。尤其是使用C语言编写设备驱动程序、嵌入式程序的时候,语言编写设备驱动程序、嵌入式程序的时候,某个变量的每一位都会有特定的含义。本章将介绍某个变量的每一位都会有特定的含义。本章将介绍C语言中的位运算。语言中的位运算。一、位
2、运算的概念一、位运算的概念 日常生活中常用十进制的数据描述事物。但是,对计算机的硬件来说,一个日常生活中常用十进制的数据描述事物。但是,对计算机的硬件来说,一个物理器件一般有两个明显的稳定状态,例如:电路的开、关状态;电平的高、低物理器件一般有两个明显的稳定状态,例如:电路的开、关状态;电平的高、低状态;磁盘上某个点的顺磁、逆磁状态;光盘上某个点的平、凹状态等。所以,状态;磁盘上某个点的顺磁、逆磁状态;光盘上某个点的平、凹状态等。所以,计算机世界是一个二进制的计算机世界是一个二进制的0、1世界,每个世界,每个0或或1是一个位。是一个位。8个位组成一个字节。个位组成一个字节。在在VC编译系统中,
3、一个编译系统中,一个int型变量占型变量占4个字节,也就是个字节,也就是32位的存储单元。位运位的存储单元。位运算可以对算可以对32个位中的任意一位进行运算。个位中的任意一位进行运算。例如:例如:int a;a=4;如图所示。如图所示。二、位运算符二、位运算符在在C语言中,提供位逻辑运算符和移位运算符。语言中,提供位逻辑运算符和移位运算符。1、位逻辑运算符、位逻辑运算符 C语言中位逻辑运算符有四种:按位与、按位或、按位异或、按位取反。语言中位逻辑运算符有四种:按位与、按位或、按位异或、按位取反。1)“按位与按位与”运算符运算符“&”参加运算的两个数据,按二进位进行参加运算的两个数据,按二进位进
4、行“与与”运算。运算。运算规则是:运算规则是:0&0=0;0&1=0;1&0=0;1&1=1;【例例11-1】3&5值是多少?值是多少?#include void main()printf(%dn,3&5);【例例11-2】-3&-5值是多少?值是多少?#include void main()printf(%dn,-3&-5);2)“按位或按位或”运算符运算符“|”两个相应的二进位中只要有一个为两个相应的二进位中只要有一个为1,该位的结果值为,该位的结果值为1。运算规则是:运算规则是:0|0=0;0|1=1;1|0=1;1|1=1;【例例11-3】060|017的值是多少?(八进制)的值是多少
5、?(八进制)#include void main()printf(%on,060|017);3)“按位异或按位异或”运算符运算符 “”参加运算的两个二进位同号,则结果为参加运算的两个二进位同号,则结果为0(假);异号则为(假);异号则为1(真)。(真)。运算规则是:运算规则是:00=0;01=1;10=1;11=0;【例例11-4】0 x390 x2a的值是多少?(十六进制)的值是多少?(十六进制)#include void main()printf(%xn,0 x390 x2a);4)“按位取反按位取反”运算符运算符“”“”是一个单目运算符,用来对一个二进制数按位取反,即将是一个单目运算符,
6、用来对一个二进制数按位取反,即将0变变1,1变变0。【例例11-5】025的值是多少?(八进制)的值是多少?(八进制)#include void main()printf(%on,025);2、移位运算符、移位运算符1)“左移左移”运算符运算符“”用来将一个数的各二进位全部左移若干位,右补用来将一个数的各二进位全部左移若干位,右补0。【例例11-6】若若a=15;a=a2;则则a的值是多少?的值是多少?#include void main()int a=15;a=a2;则则a的值是多少?的值是多少?#include void main()int a=017;a=a2;printf(%on,a)
7、;说明:说明:1)右移右移1位相当于除以位相当于除以21,右移,右移2位相当于除以位相当于除以22,右移,右移n位相当于除以位相当于除以2n。2)在右移时,需要注意符号位问题。对无符号数,右移时左边高位移入在右移时,需要注意符号位问题。对无符号数,右移时左边高位移入0。对于。对于有符号的值,如果原来符号位为有符号的值,如果原来符号位为0(该数为正),则左边也是移入(该数为正),则左边也是移入0。如果符号位原。如果符号位原来为来为1(即负数),则左边移入(即负数),则左边移入0还是还是1,要取决于所用的计算机系统:有的系统移,要取决于所用的计算机系统:有的系统移入入0,有的移入,有的移入1。(移
8、入。(移入0的称为的称为“逻辑右移逻辑右移”,即简单右移;移入,即简单右移;移入1的称为的称为“算术算术右移右移”)3)在在VC编译系统中,采用的是编译系统中,采用的是“算术右移算术右移”,即对有符号数右移时,如果符号,即对有符号数右移时,如果符号位原来为位原来为1,左面移入高位的是,左面移入高位的是1。【例例11-8】若若a=0 xfffffffe;a=a1;则则a的值是多少?的值是多少?#include void main()int a=0 xfffffffe;a=a1;printf(%dn,a);三、位运算的常用用法三、位运算的常用用法 1、置位、置位0 将某些位设置为将某些位设置为0。
9、在控制某些设备时,用于关闭某个装置,比如关闭显。在控制某些设备时,用于关闭某个装置,比如关闭显卡的输入。使用卡的输入。使用“按位与按位与”运算,在需要置为运算,在需要置为0的位上与的位上与“0”进行进行“按位与按位与”,保持不变的位与,保持不变的位与“1”进行进行“按位与按位与”。例如:将例如:将8位二进制数位二进制数01001011的最低位置为的最低位置为0,其它位不变,如图所示。,其它位不变,如图所示。2、置位、置位1 将某些位设置为将某些位设置为1。在控制某些设备时,用于启动某个装置,比如启动声卡。在控制某些设备时,用于启动某个装置,比如启动声卡的输入通道。使用的输入通道。使用“按位或按
10、位或”运算,在需要置为运算,在需要置为1的位上与的位上与“1”进行进行“按位或按位或”,保持不变的位与,保持不变的位与“0”进行进行“按位或按位或”。例如:将例如:将8位二进制数位二进制数01001010的最高位置为的最高位置为1,其它位不变,如图所示。,其它位不变,如图所示。3、位转置、位转置 将某些位设置与原来相反。在控制某些设备时,切换某个装置的状态,例如一将某些位设置与原来相反。在控制某些设备时,切换某个装置的状态,例如一个按钮,按一下启动,再按一下切换为关闭,再按一下又切换为启动。使用个按钮,按一下启动,再按一下切换为关闭,再按一下又切换为启动。使用“按位按位异或异或”运算,在需要转
11、置的位上与运算,在需要转置的位上与“1”进行进行“按位异或按位异或”,保持不变的位与,保持不变的位与“0”进行进行“按位异或按位异或”。例如:将例如:将8位二进制数位二进制数01001011的第的第2位转置,其它位不变,如图所示。位转置,其它位不变,如图所示。为了设置一个数的某些位,与这个数进行按位运算的数通常称为掩码,例如上为了设置一个数的某些位,与这个数进行按位运算的数通常称为掩码,例如上面举例中的掩码分别为面举例中的掩码分别为11111110、10000000、00000100,这个数通常用十六进制,这个数通常用十六进制的数来表示,即分别为:的数来表示,即分别为:0 xfe、0 x80、
12、0 x04。四、位运算复合赋值运算符四、位运算复合赋值运算符 位运算符与赋值运算符可以组成复合赋值运算符。即:位运算符与赋值运算符可以组成复合赋值运算符。即:&=、|=、=、=例如:例如:a&=b;相当于:相当于:a=a&b;a=2;相当于:相当于:a=a2;五、位段五、位段 C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种种以位为单位以位为单位的成员称为的成员称为“位段位段”或称或称“位域位域”。利用位段能够用较少的位。利用位段能够用较少的位数存储数据。数存储数据。例如:例如:struct bit_type unsi
13、gned a:2;/a成员占成员占2个位个位 unsigned b:6;unsigned c:4;unsigned d:4;int i;/从下一存储单元开始存放从下一存储单元开始存放 data;说明:说明:1)位段成员的类型必须指定为位段成员的类型必须指定为unsigned或或int型。型。2)若某一位段要从下一存储单元开始存放,可以用以下形式定义:若某一位段要从下一存储单元开始存放,可以用以下形式定义:unsigned a:1;unsigned b:2;unsigned :0;unsigned c:3;/从下一存储单元开始存放从下一存储单元开始存放 3)一个位段必须存储在同一存储单元中,不能
14、跨两个单元。如果第一个单元空一个位段必须存储在同一存储单元中,不能跨两个单元。如果第一个单元空间不能容纳下一个位段,则该空间不用,而从下一个存储单元开始存放。间不能容纳下一个位段,则该空间不用,而从下一个存储单元开始存放。unsigned a:1;unsigned b:2;unsigned c:30;/从下一存储单元开始存放从下一存储单元开始存放4)可以定义无名位段。可以定义无名位段。unsigned a:1;unsigned :2;/无名位段,两位空间不用无名位段,两位空间不用 unsigned b:3;unsigned c:4;5)位段的长度不能大于存储单元的长度,也不能定义位段数组。位段的长度不能大于存储单元的长度,也不能定义位段数组。【例例11-9】对位段中数据的引用。对位段中数据的引用。#include void main()struct bit_type unsigned a:2;unsigned b:6;unsigned c:4;data;data.a=3;/11 data.b=7;/000111 data.c=9;/1001 printf(%d,%d,%dn,data.a,data.b,data.c);