c语言从入门到精通__第16章课件

PPT
  • 阅读 46 次
  • 下载 0 次
  • 页数 56 页
  • 大小 272.501 KB
  • 2022-11-24 上传
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
此文档由【小橙橙】提供上传,收益归文档提供者,本网站只提供存储服务。若此文档侵犯了您的版权,欢迎进行违规举报版权认领
c语言从入门到精通__第16章课件
可在后台配置第一页与第二页中间广告代码
c语言从入门到精通__第16章课件
可在后台配置第二页与第三页中间广告代码
c语言从入门到精通__第16章课件
可在后台配置第三页与第四页中间广告代码
c语言从入门到精通__第16章课件
c语言从入门到精通__第16章课件
还剩10页未读,继续阅读
【这是免费文档,您可以免费阅读】
/ 56
  • 收藏
  • 违规举报
  • © 版权认领
下载文档30.00 元 加入VIP免费下载
文本内容

【文档说明】c语言从入门到精通__第16章课件.ppt,共(56)页,272.501 KB,由小橙橙上传

转载请保留链接:https://www.ichengzhen.cn/view-44545.html

以下为本文档部分文字说明:

第16章合理利用内存——位运算二进制数位运算符位域综合应用——数制转换跟我上机第16章C合理利用内存——位运算二进制数位运算符位域综合应用——数制转换跟我上机第16章C合理利用内存——位

运算二进制数位运算符位域综合应用——数制转换跟我上机第16章C合理利用内存——位运算二进制数位运算符位域综合应用——数制转换跟我上机第16章C合理利用内存——位运算二进制数位运算符位域综合应用——数制转

换跟我上机第16章C合理利用内存——位运算二进制数位运算符位域综合应用——数制转换跟我上机C合理利用内存——位运算数据在计算机里是以二进制形式表示的,在实际程序中,许多系统程序需要直接对二进制位数据操作,还有不少硬件设备与计算机通信都是通过一组二进制数控制和反应硬件的状

态。C语言特别提供了直接对二进制位的操作的功能,称为位运算。位运算直接对内存中二进制数据进行操作,无需转成十进制,因此处理速度非常快。位运算的正确使用,可以合理利用内存,优化程序。16.1二进制数16.1.1二进制16.1.2无符号数和有符号数16.

1.1二进制二进制就是逢二进一,比如十进制数3转换为二进制数11,十进制数10转换为二进制数1010。要把二进制数转换为十进制数,可以使用二进制的数字每一位对应一个2的某次幂,然后累加求和。比如:(1011)2=1*23+0*22+1*21+1*20=8+0+2+1=(1

1)1032323216.1.1二进制把二进制数中的每一个二进制数称为位(bit,比特),即,每个0或1就是一个位),位是数据存储的最小单位。通常,把一组4位二进制数称为半字节(nibble),一组8位二进制数称为一个字节(byte)

。通常把两个或者四个字节称为一个字(word),两个字又称之为一个双字(doubleword)。16.1.2无符号数和有符号数对一个字节而言,八位二进制数都是用来存储数据的,它只能表示非负整数,范围为0~255。二进制00000000最小,表示十进制的0;二进制

11111111最大,表示十进制的255。有符号数是通过一个字节左边第一位的二进制数来表示,0时表示整数,1表示负数。比如10000011表示-3,00000011表示3。16.1.2无符号数和有符号数问题看似很完美地解决了,再来看个特殊情况,就是十进制数0。使用00000000表示正0,使

用10000000表示负0,这样一对多的关系不利于数据的存储,程序开发也会产生很多隐患。为了解决以上问题,引入了二进制补码机制。⑴正数的时候最高位是0,不需要再求补码(数在计算机内部存储时用来表示的二进制数),或者可以理解为原码(数直接转换的二进制数)和补码是相同的,

因此00000011表示为十进制3。16.1.2无符号数和有符号数⑵负数的时候最高位是1,表示的原码先按位取反后加1(符号位不动),比如-3的原码是10000011,先按位取反变为11111100,然后再加1变成11111101,这样

11111101就是-3在计算机内部存储时用来表示它的二进制数。反之,当你知道存储器中有序列11111101,而且知道它的最高位是符号位,表示的是一个负整数,把把转变为十进制数的方法就是先减1(符号位不动),变为

11111100,然后再按位取反得10000011,即它表示的就是是-3了。注意:在这种系统中+0就是00000000,而此时的10000000则表示-128(这个特殊,不遵循补码机制,硬性规定)。16.2位运算符16.2.1按位与运算符16.2.2

按位或运算符16.2.3按位异或运算符16.2.4按位取反运算符16.2.5左移运算符16.2.6右移运算符16.2.7位运算赋值运算符16.2.8位运算应用16.2位运算符位运算符描述&按位与|按位或^按位异或~取反<<左移>>右移16.2位运算符说明:⑴位运算符

中除~以外,均为双目(元)运算符,即要求两侧各有一个运算量。⑵运算量只能是整型或字符型的数据,不能为实型数据。16.2.1按位与运算符按位与运算符“&”是双目运算符。其功能是参与运算的两数各对应的二进位相与。只有对应的两个二进位均为1时,

结果位才为1,否则为0,即:0&0=0,0&1=0,1&0=0,1&1=1注意:参与运算的数以补码形式出现。16.2.1按位与运算符1.正数的按位与运算例如:计算10&5,需要先把十进制数转换为补码形式

,再按位与运算,计算如下。0000101010的二进制补码&000001015的二进制补码00000000按位与运算,结果转换为十进制后为0所以10&5=016.2.1按位与运算符2.负数的按位与运算例如:计算-9&-

5。第1步:先转换为补码形式。-9的原码:10001001,反码:11110110,补码:11110111-5的原码:10000101,反码:11111010,补码:11111011第2步:补码进行位与运算。11110111-9的二进制补码&11111011-5的

二进制补码11110011按位与运算第3步:将结果转换为原码。补码:11110011,反码:11110010,原码:10001101,原码:-13,所以-9&-5=-1316.2.1按位与运算符3.按位与的作用按位与运算通常用来对某些位清0或保留某些位。例如要求把a的高八位清0,保

留低八位,可以使用a&255运算(255的二进制数为0000000011111111)。又比如,有一个数是01101101,希望保留从右边开始第3、4位,以到达程序的某些要求,可以这样运算:01101101&0000110000001100上式描述的就是为了保留指定位,进行的按位与

运算,如果写成十进制形式,可以写成表达式如下109&12。16.2.2按位或运算符按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的二个二进位有一个为1时,结果位就为1,即:0|0=0,0|1=1,1|0=1,1|1=1参与运算的两个数均

以补码出现。例如:10|5可写算式如下:00001010|000001010000111115的二进制补码所以10|5=1316.2.2按位或运算符常用来将源操作数某些位置1,其它位不变。首先设置一个二进制掩码mask

,执行s=s|mask,把其中特定位置1,其它位为0。比如有一个数是00000011,希望把它从右边开始第3、4位置为1,其他位不变,可以写成如下的形式:00000011|00001100=00001111即3|12=1516.2.3按位异或运算符按位异或运算符“^”是双目运算符。

其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1,即:0^0=0,0^1=1,1^0=1,1^1=0参与运算数仍以补码出现,例如10^5可写成算式如下:00001010^000001010000

111115的二进制补码所以10^5=15充分利用按位异或的特性,可以实现以下效果。16.2.3按位异或运算符⑴设置一个二进制掩码mask,执行s=s^mask,设置特定位置是1,可以使特定位的值取反;设置掩码中特定位置其它位为是0,可以保留原值。设有01111010,想使其低4位翻转,即

1变为0,0变为1。可以将它与00001111进行^运算,即:01111010^000011110111010116.2.3按位异或运算符⑵不引入第三变量,交换两个变量的值。想将a和b的值互换,可以用以下赋值语句实现

:a=a^b;b=b^a;a=a^b;分析如下:(按位异或满足交换率)a=a^b;b=b^a=b^a^b=b^b^a=0^a=a;a=a^b=a^b^a=a^a^b=0^b=b;假设a=3;b=4;验证如下:a=011^b=100a=111(a^b的结果,a变成7

)^b=100b=011(b^a的结果,b变成3)^a=11116.2.4按位取反运算符求反运算符“~”为单目运算符,具有右结合性。其功能是对参与运算的数的各二进位按位求反。例如~9的运算为:~(00001001),结果为:(11110110),如果表示无符号数是246,如果表示有符号数是

-10(按照上文的方法自己演算)。16.2.5左移运算符左移运算符“<<”是双目运算符。其功能把“<<”左边的运算数的各二进位全部左移若干位,由“<<”右边的数指定移动的位数。1.无符号数的左移如果是无符号数,则向左移动n位时,丢弃左边n位数据,并在右边填充0。如下图所示。16

.2.5左移运算符十进制n=1:00000001n<<1,十进制2:00000010n<<1,十进制4:00000100n<<1,十进制8:00001000n<<1,十进制16:00010000n<<1,十进制3

2:00100000n<<1,十进制64:01000000n<<1,十进制128:1000000016.2.5左移运算符程序到这里还都是很正常的,每次左移一位,结果是以2的幂次方不断变化,此时继续左移,产生如下的结果。n<<1,十进制

0:0000000016.2.5左移运算符2.有符号数的左移如果是有符号数,则向左移动n位时,丢弃左边n位数据,并在右边填充0,同时把最高位作为符号位。这种情况对于正数,跟上述的无符号数左移结果是一样的,不再分析,那对于负数呢,如

下图所示。16.2.5左移运算符十进制n=-128:10000001n<<1,十进制2:00000010n<<1,十进制4:00000100n<<1,十进制8:00001000n<<1,十进制16:00010000n<<1,十进制32:00100000

n<<1,十进制64:01000000n<<1,十进制128:10000000n<<1,十进制0:00000000n<<1,十进制00000000016.2.5左移运算符已经看到了有符号数左移是如何移动的。对于有符号数据的左移操作也非常简单,只不过要把最高位考虑成符号位而已,遇到1

就是负数,遇到0就是正数,就是这么简单,直到全部移除变成0。16.2.6右移运算符右移运算符“>>”是双目运算符。其功能是把“>>”左边的运算数的各二进位全部右移若干位,“>>”右边的数指定移动的位数。1.无符号数的右移如果是无符号数,则向右移动n位时,丢弃右边n位数据

,并在左边填充0。如下图所示。16.2.6右移运算符十进制n=128:10000000n>>1,十进制64:01000000n>>1,十进制32:00100000n>>1,十进制16:00010000n>>1,十进制8:00001000n>>1,十进制4:00000100n>>1,十进制2:

00000010n>>1,十进制1:0000000116.2.6右移运算符程序到这里还都是很正常的,每次右移一位,结果是以2的幂次方不断变化,此时继续右移。结果变成了0,显然结果是不对的,所以右移时一旦溢出就不再正确了。在不溢出的情况下,右移一位相当于除以2,

右移n位相当于除以2n。n>>1,十进制0:0000000016.2.6右移运算符2.右符号数的右移如果是有符号数,则向右移动n位时,丢弃右边n位数据,而左边填充的内容依赖于具体的机器,可能是1也可能是0。比如对于有符号数(10001010)来说,右移有两种情况:⑴(1000101

0)>>2=(00100010);⑵(10001010)>>2=(11100010);16.2.6右移运算符十进制n=-64:11000000n>>1,十进制-32:11100000n>>1,十进制-16:11110000n>>1,十进制-8:11111000n>>1,十进制-4:111111

00n>>1,十进制-2:11111110n>>1,十进制-1:11111111n>>1,十进制-1:1111111116.2.6右移运算符最高的符号位保持原来符号位不断右移,直到全部变成1。在不溢出的情况下,右移一位相当于除以2,右移

n位相当于除以2的n次幂。16.2.6右移运算符提示:这样左端填1来处理有符号数右移的情况,就是所谓的“算术右移”,如果右移时左端统统填0,则称之为“逻辑右移”。16.2.7位运算赋值运算符位运算赋值运算符举例

等价于&=a&=ba=a&b|=a|=ba=a|b^=a^=ba=a^b>>=a<<=2a=a<<2<<=a>>=2a=a>>216.2.8位运算应用【范例16-1】分析以下程序的位运算的结果。01#include<stdio.h>02intmain()03{04unsignedchara

,b,c;/*声明字符型变量*/05a=0x3;/*a是十六进制数*/06b=a|0x8;/*按位或*/07c=b<<1;/*左移运算*/08printf("%d\n%d\n",b,c);09retur

n0;10}16.2.8位运算应用变量a的二进制数:000000110x8的二进制数:00001000变量b的二进制数:00000011|0000100000001011十进制11的二进制码变量b左移1位,结果是:00010110所以变量c的值是十进制22。

16.2.8位运算应用【范例16-2】取一个整数a从右端开始的4~7位并输出01#include<stdio.h>02intmain()03{04unsignedshorta,b,c,d;/*声明字符型变量*/05scanf("%o",&a);06b=a>>4;/*右移

运算*/07c=~(~0<<4);/*取反左移后再取反*/08d=b&c;/*按位与*/09printf("%o\n%o\n",a,d);10return0;11}16.2.8位运算应用此范例分三步进行:先使a右移4位;然后设置一个低4位全为1,其余全为0的数

,可用~(~0<<4);最后将上面二者进行&运算。输入的八进制数是1640,转换为2进制数是:0000001110100000,获取其右端开始的4到7位是二进制数1010,转换为八进制就是12。15—83—07—415—43—016.2.8位运算应用【范例16-3】将无符号数

a右循环移n位,即将a中原来左面(16-n)位右移n位,原来右端n位移到最左面n位。01#include<stdio.h>02intmain()03{04unsignedshorta,b,c;/*声明字符型变量*/05intn;06scanf("%o,%d",&a,&n);/*输入八

进制和十进制数*/07b=a<<(16-n);/*左移运算*/08c=a>>n;/*右移运算*/09c=c|b;/*按位或*/10printf("%o\n%o\n",a,c);/*输出八进制数*/11re

turn0;12}16.2.8位运算应用题目分三步进行:将a的右端n位先放到b中的高n位中,实现语句:b=a<<(16-n);将a右移n位,其左面高位n位补0,实现语句:c=a>>n;最后c与b进行按位或运算,即c=c|b。题目中输入

的八进制数是1641,转换为2进制数是:0000001110100001,获取其循环移三位,结果是:0010000001110100,转换为八进制就是20164。n位n位a:c:16.3位域C语言可以在一个结构体中以二进制位为单位来指定其成员所占内存

长度,这种以位为单位的成员就称为位域(bitfield)。如何以位作为单位来访问数据呢?这样可以更高效的使用存储空间,方法就是使用位域,这样就可以在一个字节中分别存放多个的信息。16.3位域structdata/*定义结构体*/{unsigne

dn1:6;/*n1占6个位*/unsignedn2:4;/*n2占4个位*/unsignedn3:4;/*n3占4个位*/unsignedn4:2;/*n4占2个位*/}mydata;n1n2n3n416.3位域在使用位域时,需要注意以下情况:⑴一个位域必须存储在同一个存储单元中,

不能跨两个单元。可以闲置没有使用的存储单元,但是对那种一个剩余存储单元放不下的,就从下一个单元开始存放。而且定义的每一个位域长度不能超过你存储单元。比如你有一个字节去使用,总共8位,你却申请了一个位域是9位

的,这就是错误的。16.3位域⑵位域名缺省时称作无名位域。例如:structdate/*定义结构体*/{unsigneda:2;/*a占2个位*/unsigned:2;/*空2个位*/unsignedb:1;

/*b占1个位*/}mydate;第二次申请的2个空间的位域,是闲置不适用的,因为没有位域名称。需要注意的是,同样是无名的位域,它的存储空间是0,有特殊的含义,它指的是这个字节剩余的不再使用,从下个新字

节开始存储。例如:structdate/*定义结构体*/{unsigneda:2;/*a占2个位*/unsigned:0;/*从下一个新字节开始存储*/unsignedb:1;/*b占1个位*/}mydate;16.3位域⑶一个结构体中

既可以定义位域成员也可以同时定义一般的结构体成员。例如:structdate/*定义结构体*/{unsigneda:2/*a占2个位*/unsignedb:1;/*b占1个位*/intk;/*int类型变量*/}mydata;16.3位域⑷不

能定义以位域结构为元素的数组。关于位域的引用与结构体相同。例如:mydata.a=2;/*赋值*/mydata.b=1;/*赋值*/需要注意的是,a只占两位,在上结构体中有声明,也就是说a最大存储的二进制数是

11,转换为十进制就是3,如果写成:mydata.a=10;这并不错,但是结果就不是期望的10了,变成了2,因为10的二进制码是1010,只截取右边两位10,故结果是2。16.3位域⑸位域也可以参与算术表达式的运算,这时系统自动将

其转化为整型数。位域可以用整型格式符输出。例如:printf(“%d\n”,mydata.a);/*a以有符号整数形式输出*/printf(“%u\n”,mydata.a);/*a以无符号整数形式输出*/16.4综合应用—

—数制转换【范例16-4】从键盘上输入一个十进制正整数,按二进制位输出该数。16.6跟我上机1.编写C程序,将无符号数a左循环移n位,即将a中原来左面n位左移n位,位移到最右面n位。16.6跟我上机2.编写C程序,将十六进制数转换成二进制。

小橙橙
小橙橙
文档分享,欢迎浏览!
  • 文档 25747
  • 被下载 7
  • 被收藏 0
相关资源
广告代码123
若发现您的权益受到侵害,请立即联系客服,我们会尽快为您处理。侵权客服QQ:395972555 (支持时间:9:00-21:00) 公众号
Powered by 太赞文库
×
确认删除?