《C21第12章 位运算.ppt》由会员分享,可在线阅读,更多相关《C21第12章 位运算.ppt(21页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、新编C语言程序设计教程 清华大学出版社周二强 软件学院 计算机科学与工程系配套视频:配套视频: 博客:博客: 位运算位运算12.1 12.1 位操作符位操作符12.1.1 按位与操作符&12.1.2 按位或操作符12.1.3 异或操作符12.1.4 取反操作符12.1.5 左移操作符12.2 12.2 位运算示例位运算示例12.3 12.3 位段位段位运算位运算是指按二进制位进行的运算,实际上就是直接对整数在内存中的二位运算是指按二进制位进行的运算,实际上就是直接对整数在内存中的二进制位进行操作。进制位进行操作。考虑这样的问题:编程控制编号为考虑这样的问题:编程控制编号为0 0至至7 7的八盏
2、灯的开关。的八盏灯的开关。可以定义一个长度为可以定义一个长度为8 8的短整型数组变量的短整型数组变量a a。可以定义一个无符号的字符型变量可以定义一个无符号的字符型变量c c。如果如果c c的值为的值为128128(1000 00001000 0000),则),则7 7号灯亮,其余灯灭;为号灯亮,其余灯灭;为192192时(时(1100 1100 00000000),则),则6 6号和号和7 7号灯亮,其余的灭。号灯亮,其余的灭。但是要改变某盏灯的状态而不影响其他灯的,却并非易事。但是要改变某盏灯的状态而不影响其他灯的,却并非易事。位操作符C C语言提供的位操作符有按位与语言提供的位操作符有按
3、位与&、按位或、按位异或、按位或、按位异或、取反、取反、左移左移。位操作符的操作数仅限整型(字符型),位操作符的操作数仅限整型(字符型),为简明下面示例中位操作符的操作数多为字符型。为简明下面示例中位操作符的操作数多为字符型。return12.1.1 12.1.1 按位与操作符按位与操作符&按位与操作符按位与操作符&将参与运算的两个操作数,按二位进制位进行将参与运算的两个操作数,按二位进制位进行“与与”运算。与运算时,如果两个二进制位上的数均为运算。与运算时,如果两个二进制位上的数均为1 1,则运算结果的相,则运算结果的相应位为应位为1 1,否则运算结果的相应位为,否则运算结果的相应位为0 0
4、。即。即1&1=11&1=1、1&0=01&0=0、0&1=00&1=0、0&0=00&0=0例如:例如:char a=-2,b=3char a=-2,b=3,则,则a&ba&b的值为的值为2 2。按位与操作符&从按位与操作符从按位与操作符&的运算规则可知,利用按位与操作符的运算规则可知,利用按位与操作符&可以很容易可以很容易地在不影响其它位的情况下将一个整数的某位设置为地在不影响其它位的情况下将一个整数的某位设置为0 0。例如,无符号字符型例如,无符号字符型c c的值为的值为165165(1010 01011010 0101),即现在是第),即现在是第0 0、2 2、5 5、7 7号灯亮。需
5、熄灭第七号灯时,号灯亮。需熄灭第七号灯时,只要让只要让c c与与0 x7f0 x7f(0111 11110111 1111)进行按位与运算即可。)进行按位与运算即可。注意:1.1.按位与操作符也可以构成复合赋值操作符,即按位与操作符也可以构成复合赋值操作符,即c=c&0 x7fc=c&0 x7f可改可改写为写为c&=0 x7fc&=0 x7f。2.2.利用按位与操作符对整型变量利用按位与操作符对整型变量a a的各位进行取舍时,如果保留某的各位进行取舍时,如果保留某位的值,则另一操作数的对应位值为位的值,则另一操作数的对应位值为1 1;如果清零,则对应位的值为;如果清零,则对应位的值为0 0。1
6、&1=11&1=1、1&0=01&0=0、0&1=00&1=0、0&0=00&0=0return12.1.2 12.1.2 按位或操作符按位或操作符按位或操作符将参与运算的两个操作数,按二进制位进行按位或操作符将参与运算的两个操作数,按二进制位进行“或或”运算。或运算时,如果两个二进制位上的数都为运算。或运算时,如果两个二进制位上的数都为0 0,则运算结果的对,则运算结果的对应位为应位为0 0;否则,对应位为;否则,对应位为1 1。即。即1|1=11|1=1、1|0=11|0=1、0|1=10|1=1、0|0=00|0=0。由运算规则可知,利用按位或操作符可以很容易地在不影响其它由运算规则可知
7、,利用按位或操作符可以很容易地在不影响其它位的情况下将一个整数的某位设置为位的情况下将一个整数的某位设置为1 1。例如,无符号字符型例如,无符号字符型c c的值为的值为165165,需点亮,需点亮1 1号灯时,只要让号灯时,只要让c c与与0 x20 x2作作按位或运算即可。按位或运算即可。c|=0 x2 c|=0 x2 return12.1.3 异或操作符 异或操作符异或操作符 也称也称xorxor操作符。操作符。“异或异或”指参与运算的两个二进制位是否为指参与运算的两个二进制位是否为异(不同),不同时结果为异(不同),不同时结果为1 1(真),相同时结果为(真),相同时结果为0 0(假)。
8、即(假)。即1 1=01 1=0、1 0=11 0=1、0 1=10 1=1、0 0=00 0=0。分析运算规则可知,某位与分析运算规则可知,某位与1 1进行异或运算时,结果与该位正好相反(翻进行异或运算时,结果与该位正好相反(翻转),即转),即1 1变变0 0,0 0变变1 1;某位与;某位与0 0进行异或时,结果与该位相同。进行异或时,结果与该位相同。例如,无符号字符型例如,无符号字符型c c的值为的值为165165,需把第,需把第0 0到到3 3号灯的状态进行翻转时即亮号灯的状态进行翻转时即亮的灭,灭的亮,只要让的灭,灭的亮,只要让c c与与0 xf0 xf作异或操作即可。作异或操作即可
9、。c=0 xfc=0 xfreturn12.1.4 12.1.4 取反操作符取反操作符 取反操作符是一个单目操作符,用来对一个整数按二进制位取反,取反操作符是一个单目操作符,用来对一个整数按二进制位取反,即即0 0变变1 1,1 1变变0 0。例如,无符号字符型例如,无符号字符型c c的值为的值为165165,需把所有灯的状态进行翻转时,需把所有灯的状态进行翻转时,只要让进行取反操作即可。只要让进行取反操作即可。c=cc=c。整数整数a a的相反数可以表示为的相反数可以表示为a+1a+1。因为因为aa等价于等价于-1-a-1-a,故,故a+1a+1的值为的值为-1-a+1-1-a+1为为-a-
10、a。return12.1.5 12.1.5 左移操作符左移操作符左移操作符左移操作符常用形式为:常用形式为:a na n其中,其中,a a和和n n均为整数,表达式求值时将均为整数,表达式求值时将a a的二进制位全部左移的二进制位全部左移n n位,位,右端补右端补n n个个0 0,左端移出的,左端移出的n n位因溢出而舍弃。显然位因溢出而舍弃。显然n n的取值范围通常为的取值范围通常为1 1至至sizeof(asizeof(a)。左移左移1 1位的值为位的值为a a的的2 2倍,左移倍,左移2 2位的值为位的值为a a的的4 4倍,倍,(表达式的值(表达式的值不能超出整型的取值范围)。左移操作
11、要比相应的乘法运算(不能超出整型的取值范围)。左移操作要比相应的乘法运算(a*2a*2)快得多。快得多。在位运算中,左移运算常用于构造操作数。在位运算中,左移运算常用于构造操作数。构造操作数无符号字符型变量无符号字符型变量c c的值为的值为165165,需点亮第,需点亮第6 6号灯,可以用如下表达式号灯,可以用如下表达式c|=1 6c|=1 6,其中,其中,1 61 右移操作符与左移操作符类似,表达式右移操作符与左移操作符类似,表达式a na n求值时,会将求值时,会将a a的二进的二进制位全部右移制位全部右移n n位,右端移出的位,右端移出的n n位因溢出而被舍弃。位因溢出而被舍弃。根据左端
12、移入数的不同,右移操作分为根据左端移入数的不同,右移操作分为“逻辑右移逻辑右移”和和“算术右移算术右移”两种。两种。逻辑右移时,无论逻辑右移时,无论a a为何类型,左端均移入为何类型,左端均移入n n个个0 0;算术右移时,如果;算术右移时,如果a a为无符号数,则左端移入为无符号数,则左端移入n n个个0 0;如果;如果a a为有符号数,则左端移入的数为有符号数,则左端移入的数为为a a的符号位,即的符号位,即a a为正数时移入为正数时移入0 0,a a为负数时移入为负数时移入1 1。TCTC和和VC6.0VC6.0中均中均采用算术右移。采用算术右移。例12-1 分析下面求整数绝对值的函数
13、分析:分析:如果如果x=0,x=0,则则y y的值为的值为0 0,(x y)-y(x y)-y 的结果仍为的结果仍为x x。如果如果x0,x0,则则y y的值为的值为-1-1,x x与与y y进行异或运算实际上为对进行异或运算实际上为对x x进行取反操作,进行取反操作,减减y y就是加就是加1 1。x x取反加取反加1 1的结果就是的结果就是x x的相反数,即的相反数,即-x-x。return12.2 12.2 位运算示例位运算示例例例12-2 12-2 用无符号字符型的一位控制编号为用无符号字符型的一位控制编号为0 07 7的八盏灯中的一盏,的八盏灯中的一盏,为为1 1时相应的灯亮,否则灯灭
14、。随机生成时相应的灯亮,否则灯灭。随机生成2020个个0 07 7的整数,根据整数的整数,根据整数调整相关编号灯的开关。如整数为调整相关编号灯的开关。如整数为5 5,则,则5 5号灯亮时关掉它,灭时打开号灯亮时关掉它,灭时打开它。最初时八盏灯均不亮,编程输出最终灯的状态。它。最初时八盏灯均不亮,编程输出最终灯的状态。例12-2例12-3把一个整数32位中的高16位和低16位互换。return12.3 位段 通过位运算能够以位为单位使用内存空间,如可以设置、改变或读通过位运算能够以位为单位使用内存空间,如可以设置、改变或读取一个或多个二进制位的值,但是这些操作不但麻烦而且极易出错。取一个或多个二
15、进制位的值,但是这些操作不但麻烦而且极易出错。C C语言提供了语言提供了“位段位段”,利用位段,可以方便的实现类似操作。,利用位段,可以方便的实现类似操作。C C语言允许在一个结构体中以位为单位指定其成员实际存储空间的长语言允许在一个结构体中以位为单位指定其成员实际存储空间的长度,结构体中指定存储长度的成员就是所谓的位段。度,结构体中指定存储长度的成员就是所谓的位段。结构体中的结构体结构体结构体structstruct bitfieldbitfield虽然有三个整型成员虽然有三个整型成员a,b,ca,b,c,但它们存储空间但它们存储空间的长度只有的长度只有2 2位、位、4 4位和位和2 2位。
16、位。特别强调,整型成员特别强调,整型成员a a、b b、c c虽然位数不多,但仍为有符号数,即虽然位数不多,但仍为有符号数,即a a、c c的取值范围为的取值范围为-2-2至至1 1,b b的取值范围为的取值范围为-8-8至至7 7。位段位段仅仅是自定义了存储空间的长度,使用时与正常的结构体成员位段仅仅是自定义了存储空间的长度,使用时与正常的结构体成员相同,如相同,如bf.abf.a=1=1,bf.bbf.b=-8=-8等。等。当参与运算时,位段会自动转换成整型,当给位段赋一个超出其取当参与运算时,位段会自动转换成整型,当给位段赋一个超出其取值范围的值时,左端多余的位数会被舍弃。值范围的值时,
17、左端多余的位数会被舍弃。位段类型转换和赋值的原则与位段类型转换和赋值的原则与C C语言基本类型所遵循的原则相同,如语言基本类型所遵循的原则相同,如printf(%d,%dnprintf(%d,%dn,bf.abf.a+bf.bbf.b,bf.cbf.c=15)=15)的输出为的输出为-7,-1-7,-1。关于位段,需注意:1.1.位段的类型只能为整型(有符号,无符号及字符型)。位段的类型只能为整型(有符号,无符号及字符型)。2.2.位段的自定义长度不能大于其默认的长度。位段的自定义长度不能大于其默认的长度。3.3.位段的具体实现通常与编译系统相关。位段的具体实现通常与编译系统相关。return