C语言ppt精选第12章位运算.ppt
教学内容:教学内容:12.1 12.1 位逻辑运算位逻辑运算 12.2 12.2 位移位运算位移位运算 12.3 12.3 复合位运算复合位运算 12.4 12.4 位段位段 教学要求:教学要求:1.1.掌握按位与运算、按位或运算、按位异或运算、掌握按位与运算、按位或运算、按位异或运算、取反运算、左移运算、右移运算的运算规则取反运算、左移运算、右移运算的运算规则。2.2.掌握位段的应用。掌握位段的应用。第第1212章章 位位 运运 算算 为了节省内存空间,在系统软件中常将多个标志状为了节省内存空间,在系统软件中常将多个标志状态简单地组合在一起,存储到一个字节(或字)中。态简单地组合在一起,存储到一个字节(或字)中。语言语言 提供了实现将标志状态从标志字节中分离出来的位提供了实现将标志状态从标志字节中分离出来的位运算功能。运算功能。C 既具有高级语言的特点,又具有低级语言的功能,既具有高级语言的特点,又具有低级语言的功能,位运算能力就是其特色之一。位运算能力就是其特色之一。位运算就是指进行二进制位的运算。位运算就是指进行二进制位的运算。C提供的位运算提供的位运算有:有:名称名称 运算符运算符 名称名称 运算符运算符 按位与按位与&按位异或按位异或 按位或按位或|左移左移 12.1 12.1 位位 逻逻 辑辑 运运 算算 1.1.位运算说明位运算说明 (1 1)位位运运算算的的操操作作数数,只只能能是是整整型型或或字字符符型型数数据据,不能为实型数据。不能为实型数据。(2 2)位位运运算算符符中中除除按按位位取取反反“”为为单单目目运运算算符符外外,其余均为二目运算符,即要求两侧各有一个运算量。其余均为二目运算符,即要求两侧各有一个运算量。(3 3)参参与与运运算算时时,操操作作数数都都必必须须首首先先转转换换成成二二进进制制形式,然后再执行相应的按位运算。形式,然后再执行相应的按位运算。2.2.按位与运算符按位与运算符 (1)(1)按位与运算符:按位与运算符:&(2)(2)按位与运算格式:按位与运算格式:操作数操作数&操作数操作数 (3)(3)按位与运算规则按位与运算规则 将将2 2个个操操作作数数先先转转换换成成二二进进制制数数(补补码码),当当参参加加运运算算的的2 2个个二二进进制制数数之之对对应应位位都都为为1 1,则则该该位位的的结结果果为为1 1,否否则则为为0 0,即:即:0&0=0 0&1=0 1&0=0 1&1=1 例:例:3&5=13的补码:的补码:0 0 0 0 0 0 1 15的补码:的补码:0 0 0 0 0 1 0 1 3&5 0 0 0 0 0 0 0 1 取一个数中的某些指定位清零如:取一个数中的某些指定位清零如:a:0 0 1 0 1 1 0 0 1 0 1 0 1 1 0 0 b:0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 (377)8 a&b 0 0 0 0 0 0 0 0 1 0 1 0 1 1 0 0 结果得到结果得到 a 的低的低 8 位位(4)(4)按位与运算作用按位与运算作用main()int x,y;x=25;y=568;printf(“x&y:%dn”,x&y);printf(“3&14:%dn”,3&14);printf(“3&14:%dn”,3&14);printf(“12&12:%dn”,12&12);运行结果运行结果:x&y:24 3&14:2 3&14:12 12&12:12 例例12.1 编程对两个整型变量、整型常量分别进行按编程对两个整型变量、整型常量分别进行按位与运算,并输出它们的值。程序如下位与运算,并输出它们的值。程序如下 3.按位或运算按位或运算 (1 1)按位或运算符:)按位或运算符:|(2 2)按位或运算格式:)按位或运算格式:操作数操作数 操作数操作数 (3 3)运算规则:)运算规则:参加运算的两个运算量之对应位参加运算的两个运算量之对应位,只要有只要有一个为一个为1 1,则该位的结果为,则该位的结果为1 1。即:。即:0 0=0 0 1=1 1 0=1 1 1=1 例如:例如:00110000 (060)8 00001111 (017)8 00111111 (077)8 一个数与一个数与017进行按位或运算,可将该数的低进行按位或运算,可将该数的低4位位全置为全置为1 1;与;与0377进行按位或运算,可将该数的低进行按位或运算,可将该数的低8位全置为位全置为1。4.异或运算异或运算 (1 1)运算符)运算符 (2 2)按位异或运算格式:按位异或运算格式:操作数操作数 操作数操作数 (3 3)按位异或运算规则:按位异或运算规则:参加运算的两个运算量参加运算的两个运算量的对应位相同,则该位的结果为的对应位相同,则该位的结果为0 0。否则为。否则为1 1。即:。即:0 0=0 0 1=1 1 0=1 1 1=0 (4 4)运算的用途:使指定的位翻转)运算的用途:使指定的位翻转 如:如:01111010 00001111 对应原数的低对应原数的低4位均置为位均置为1 01110101 原数的低原数的低4位被翻转位被翻转 5.5.取反运算取反运算 (1 1)运算符)运算符 (2 2)按位取反运算格式:按位取反运算格式:操作数操作数 (3 3)按位取反运算规则按位取反运算规则 :是对一个二进制数按位取反,是对一个二进制数按位取反,即将即将0 0变为变为1 1,1 1变为变为0 0。例如:例如:a 的补码:的补码:0 0 0 0 1 1 0 0 1 0 0 1 0 0 1 1 a 1 1 1 1 0 0 1 1 0 1 1 0 1 1 0 0 (4 4)按位取反运算主要用途按位取反运算主要用途 按位取反运算主要用途是间接地构造一个数,以增强程按位取反运算主要用途是间接地构造一个数,以增强程序的可移植性。例如,通过求序的可移植性。例如,通过求 0 0,可以间接地构造一个,可以间接地构造一个各位全各位全1 1的二进制数。的二进制数。main()int x=25;unsigned int y=0;printf(“25:%dn”,25);printf(“x:%dn”,x);printf(“y(1):%dn”,y);printf(“y(2):%un”,y);运行结果运行结果:25:26 x:24 y(1):1 y(2):65535例例12.212.2 编程输出按位取反运算的值。程序如下编程输出按位取反运算的值。程序如下:12.2 12.2 位位 移移 位位 运运 算算 1.1.按位左移运算按位左移运算 (1)(1)按位左移运算符:按位左移运算符:(2)(2)按位左移运算格式:按位左移运算格式:操作数操作数移位数移位数 (3)(3)按位左移运算规则按位左移运算规则:将一个操作数先转换成二将一个操作数先转换成二进制数,然后将二进制数各位左移若干位,并在低进制数,然后将二进制数各位左移若干位,并在低位补若干个位补若干个0 0,高位左移后溢出,舍弃不起作用。,高位左移后溢出,舍弃不起作用。(4)(4)按位左移按位左移运算用途运算用途:将乘以将乘以 2 2n n 的幂运算处理的幂运算处理为左移为左移 n n 位。位。例如:例如:72 按位左移表达式的值:按位左移表达式的值:2828 例例12.3 变量的位运算符变量的位运算符#include main()unsigned a;a=7 (2)(2)按位右移运算格式:按位右移运算格式:操作数操作数移位数值移位数值 (3)(3)按位右移运算规则按位右移运算规则:将一个操作数先转换成二进制数,将一个操作数先转换成二进制数,然后将二进制数各位右移若干位,移出的低位舍弃;并在高然后将二进制数各位右移若干位,移出的低位舍弃;并在高位补位,补位分位补位,补位分2 2种情况种情况:若为无符号数,右移时左边高位移入若为无符号数,右移时左边高位移入0 0。若为有符号数,如果原来符号位为若为有符号数,如果原来符号位为0(0(正数正数),则左边,则左边补若干补若干0 0;如果原来符号位为;如果原来符号位为1 1,左边补若干,左边补若干0 0的称为的称为“逻逻辑右移辑右移”,左边补若干,左边补若干1 1的称为的称为“算术右移算术右移”。如:如:a:8 逻辑右移逻辑右移 a1:得得045766 算术右移算术右移 a1:得得145766 (4)(4)按位右移运算主要用途按位右移运算主要用途按按位位右右移移运运算算主主要要用用途途是是对对操操作作数数做做除除法法运运算算,即即将将一一个个操操作作数数除除以以 2 2n n 的的幂幂运运算算处处理理为为右右移移 n n 位位的的按按位位右右移移运运算算。右右移移一一位位相相当当于于除除以以2 2,右右移移 n n 位位相相当于除以当于除以2 2n n。例例12.412.4 从从键键盘盘上上输输入入1 1个个正正整整数数给给intint变变量量n n,输出由输出由8 81111位构成的数(从低位、位构成的数(从低位、0 0号开始编号)。号开始编号)。基本思路基本思路:(1 1)使变量)使变量n n右移右移8 8位,将位,将8 81111位移到低位移到低4 4位上位上 (2 2)构造)构造1 1个低个低4 4位为位为1 1、其余各位为、其余各位为0 0的整数。的整数。(3 3)与)与n n 进行按位与运算。进行按位与运算。(4 4)输出与运算结果。)输出与运算结果。程序如下程序如下:main()int n,mask;printf(Input a integer number:);scanf(%d,&n);/*右移右移8 8位,将位,将8 81111位移到低位移到低4 4位上位上*/n=8;/*间接构造间接构造1 1个低个低4 4位为位为1 1、其余各位为、其余各位为0 0的整数的整数*/mask=(0(7 4+1)a4 设置一个低设置一个低4位全为位全为1,其余全为其余全为0 的数。即:的数。即:(0 4;/b=a(m-n+1)/c=(04);/c=(0n)/d=b&c;printf(“%on%on”,a,d);运行情况:运行情况:1331 1331 15 字母字母o0 000 001 011 011 0010 000 000 000 101 101 ab 例例12.6从键盘上输入从键盘上输入1个正整数给整型变量个正整数给整型变量n,按二进制位输出该数。,按二进制位输出该数。#include stdio.h main()int n,mask,i;printf(Input a integer number:);scanf(%d,&n);/*构造构造1个最高位为个最高位为1、其余各位为、其余各位为0的整数的整数(屏蔽字屏蔽字)*/mask=115;printf(%d=,n);for(i=1;i=16;i+)putchar(n&mask?1:0);/*输出最高位的值输出最高位的值(1/0)*/n=1;/*将次高位移到最高位上将次高位移到最高位上*/if(i%4=0)putchar(,);/*四位一组,用逗号分开四位一组,用逗号分开*/printf(bBn);程序运行情况:程序运行情况:Input a integer number:1000 1000=0000,0011,1110,1000B 1.1.复合位赋值运算符:复合位赋值运算符:复复合合按按位位与与赋赋值值运运算算符符&=复复合合按按位位或或赋赋值值运运算算符符 =复合按位异或赋值运算符复合按位异或赋值运算符 =复合按位左移赋值运算符复合按位左移赋值运算符 =2.2.复合位赋值运算规则复合位赋值运算规则复合位赋值运算规则与复合算术赋值运算规则相同复合位赋值运算规则与复合算术赋值运算规则相同。运算符运算符 表达式表达式 等价表达式等价表达式&=x&=m x=x&m =x =m x=x m =x =m x=xm =x=n x=x=x=n x=xn 12.312.3 复复 合合 位位 运运 算算12.4 12.4 位位 段段 C语言引入位段类型。使得当存储语言引入位段类型。使得当存储1个个信息只需二进制的若干位时,二进制的信息只需二进制的若干位时,二进制的1个个(或多个)位就够用,就可以不必占用(或多个)位就够用,就可以不必占用1个个字节。字节。如果仍然使用结构类型,则造成内存空如果仍然使用结构类型,则造成内存空间的浪费。为此,间的浪费。为此,C语言引入了位段类型。语言引入了位段类型。1.1.位段的概念与定义位段的概念与定义 (1 1)位段类型:位段类型是一种特殊的结构类型,位段类型:位段类型是一种特殊的结构类型,其所有成员均以二进制位为单位定义长度,并称成员为其所有成员均以二进制位为单位定义长度,并称成员为位段。位段。(2 2)位段类型的定义位段类型的定义 位段类型的定义格式:位段类型的定义格式:struct 位段类型名位段类型名 类型说明符类型说明符 成员名成员名1:1:长度;长度;类型说明符类型说明符 成员名成员名2:2:长度;长度;;位段类型成员的数据类型只能是:位段类型成员的数据类型只能是:int、unsigned int (3 3)位段类型变量的定义位段类型变量的定义 先定义位段类型,再定义位段类型变量。先定义位段类型,再定义位段类型变量。struct 位段类型名位段类型名 类型说明符类型说明符 成员名成员名1:1:长度长度;类型说明符类型说明符 成员名成员名2:2:长度长度;struct 位段类型名位段类型名 变量名表列变量名表列;定义位段类型同时定义位段类型变量定义位段类型同时定义位段类型变量。struct 位段类型名位段类型名 类型说明符类型说明符 成员名成员名1:1:长度长度;类型说明符类型说明符 成员名成员名2:2:长度长度;变量名表列变量名表列;例如,例如,CPUCPU的状态寄存器,按位段类型定义如下:的状态寄存器,按位段类型定义如下:struct status unsigned sign:1;/*符号标志符号标志*/unsigned zero:1;/*零标志零标志*/unsigned carry:1;/*进位标志进位标志*/unsigned parity:1;/*奇偶奇偶/溢出标志溢出标志*/unsigned half_carry:1;/*半进位标志半进位标志*/unsigned negative:1;/*减标志减标志*/flags;显显然然,对对CPUCPU的的状状态态寄寄存存器器而而言言,使使用用位位段段类类型型(仅仅需需1 1个个字字节节),比比使使用用结结构构类类型型(需需要要6个个字字节节)节节省省了了5 5个个字节。字节。2.说明说明(1)因因为为位位段段类类型型是是一一种种结结构构类类型型,所所以以位位段段类类型型和和位位段段变变量量的的定定义义,以以及及对对位位段段(即即位位段段类类型型中中的的成成员员)的引用,均与结构类型和结构变量一样。的引用,均与结构类型和结构变量一样。(2)对对位位段段赋赋值值时时,要要注注意意取取置置范范围围。一一般般地地说说,长度为长度为n的位段,其取值范围是:的位段,其取值范围是:0(2n-1)。)。(3)使使用用长长度度为为0的的无无名名位位段段,可可使使其其后后续续位位段段从从下下1个字节开始存储。个字节开始存储。例如,例如,struct status unsigned sign:1;/*符号标志符号标志*/unsigned zero:1;/*零标志零标志*/unsigned carry:1;/*进位标志进位标志*/unsigned:0;/*长度为长度为0 0的无名位段的无名位段*/unsigned parity:1;/*奇偶奇偶/溢出标志溢出标志*/unsigned half_carry:1;/*半进位标志半进位标志*/unsigned negative:1;/*减标志减标志*/flags;原原本本6 6个个标标志志位位是是连连续续存存储储在在1 1个个字字节节中中的的。由由于于加加入入了了1 1个个长长度度为为0 0的的无无名名位位段段,所所以以其其后后的的3 3个个位位段段,从从下下1 1个字节开始存储,一共占用个字节开始存储,一共占用2 2个字节。个字节。(4)1个个位位段段必必须须存存储储在在1个个存存储储单单元元(通通常常为为1字字节节)中中,不不能能跨跨2个个。如如果果本本单单元元不不够够容容纳纳某某位位段段,则从下则从下1个单元开始存储该位段。个单元开始存储该位段。(5)可可以以用用%d、%x、%u和和%o等等格格式式字字符符,以以整整数形式输出位段。数形式输出位段。(6)在在数数值值表表达达式式中中引引用用位位段段时时,系系统统自自动动将将位段转换为整型数。位段转换为整型数。