版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
程序设计技术基础程序设计技术基础第十一章位运算11.1数字系统、位和字节11.2位运算符与位运算11.3位运算应用程序举例11.4位
段2022/12/242第十一章位运算11.1数字系统、位和11.1数字系统、位和字节11.1.1数字系统数制也称计数制,是用一组固定的符号和统一的规则来表示数值的方法。按进位的方法进行计数,称为进位计数制。如在日常生活中使用的十进制,在计算机中采用的二进制,以及八进制、十六进制等都是进位计数制。一种进位计数制包含一组数码符号和两个基本要素:基数和位权。2022/12/24311.1数字系统、位和字节11.1.1数字系统201.数码数码是指数制中表示基本数值大小的不同符号。例如十进制有10个数码:0、1、2、3、4、5、6、7、8、9。二进制有2个数码:0、1。八进制有8个数码:0、1、2、3、4、5、6、7。十六进制有16个数码:0~9和A、B、C、D、E、F。2022/12/2441.数码2022/12/1642.基数基数是指数制所使用数码的个数。例如,二进制的基数为2;十进制的基数为10。在运算中,当某一位上达到或超过基数大小时,就会向前进一。如十进制满十进一,二进制满二进一,十六进制则满十六进一。2022/12/2452.基数2022/12/1653.位权位权是指数制中每一固定位置对应的单位值。一个数据在某个位置上的值等于该数字与这个位置上的因子的乘积,而该因子的值是由所在位置相对于小数点的距离来确定的,这个因子就是位权,即各进位制中位权的值是基数的若干次幂。例如:十进制的123:1的位权是102=100,2的位权是101=10,3的位权是100=1;二进制中的1101,第一个1的位权是23=8,第二个1的位权是22=4,0的位权是21=2,第三个1的位权是20=1。2022/12/2463.位权2022/12/166任意的R进制数N按位权展开形式如下:其中:ri为计数制中任一个数码,R为基数。为了区分不同数制的数据,可以用括号加基数下标表示数据所属的数制。如:十进制数309.84的位权展开式为:(309.84)10=3×102+0×101+9×100+8×10-1+4×10-2二进制数11011.01的位权展开式为:(11011.01)2=1×24+1×23+1×21+1×20+1×2-22022/12/247任意的R进制数N按位权展开形式如下:2022/12/16711.1.2位和字节在计算机中,表示信息的单位有位、字节、兆、吉等,它们是表示信息量大小的基本概念。1.位(bit)位,音译为“比特”,是计算机内构成信息的最小数据单位,即一个1或0。一般用小写字母“b”表示。一位二进制可表示21=2个信息,如:是或否,有或无,真与假等。2022/12/24811.1.2位和字节在计算机中,表示信息的单位有位、字节、2.字节(Byte)字节是计算机数据存储和处理信息的基本数据单位。简记为“B”规定1个字节为8位,即8个二进制位是一个字节。
1B=8b。2022/12/2492.字节(Byte)2022/12/169存储器的存储容量除了以位、字节为单位来度量外,还需要一些更大的单位,有KB、MB、GB、TB等度量单位:1KB=210B=1024B(K代表“千”)1MB=220B=210×210B=1024×1024B(M代表“兆”)1GB=230B=210×210×210B=1024×1024×1024B(G代表“吉”)1TB=240B=210×210×210×210B=1024×1024×1024×1024B(T代表“太”)2022/12/2410存储器的存储容量除了以位、字节为单位来度量外,还需要一些更大11.2位运算符与位运算C语言的位运算可以分为位逻辑运算与位移位运算,共计6种基本位运算符:注:(1)位运算符中,除~是单目运算符外,其余均为双目运算符;(2)运算量只能是整型或字符型的数据,不能为实型数据2022/12/2411运算符含义运算符含义&按位与|按位或︿按位异或~按位取反<<左移>>右移11.2位运算符与位运算C语言的位运算可以分为位逻辑运11.2.1位逻辑运算符与运算1.“按位与”运算(&)
“按位与”是指参加运算的两个数据,按对应的二进制位分别进行“逻辑与”运算。如果两个相应的二进制位都为1,则该位的运行结果为1(真);否则为0(假)。0&0=0;0&1=0;1&0=0;1&1=12022/12/241211.2.1位逻辑运算符与运算1.“按位与”运算(&)2例如:13&10=?00001101(=13)(&)00001010(=10)
00001000(=8)2022/12/2413例如:13&10=?2022/12/1613“按位与”运算有一些特殊的用途:2022/12/2414(1)清零:若想将某个二进制数的指定位清零,可将待清零位与0进行“按位与”运算,其余位与1进行“按位与”运算;若想将该数各位都清零,可使其与零进行“按位与”运算。【例11-6】将字符变量ch所占的字节单元清零。
“按位与”运算有一些特殊的用途:2022/12/1614(【例11-6】将字符变量ch所占的字节单元清零。程序如下:#include<stdio.h>intmain(){charch=67;printf("ch=%d\n",ch);ch=ch&0;printf("ch&0后ch=%d\n",ch);return0;}2022/12/2415程序运行结果为:ch=67ch&0后ch=0【例11-6】将字符变量ch所占的字节单元清零。程序如下:2(2)保留指定位:若想保留某个二进制数中的指定位。可将指定位与1进行“按位与”运算,其余位与0进行“按位与”运算即可实现。例如对一个十六位二进制整数a,若想要将其高八位清0,而保留其低八位。则进行:a&0000000011111111运算即可:0000000100110100(a=308)
(&)0000000011111111(=255)0000000000110100(=52)2022/12/2416(2)保留指定位:若想保留某个二进制数中的指定位。可将指定位2.“按位或”运算(|)按位或”是指参加运算的两个数据,按对应的二进制位分别进行“逻辑或”运算。如果两个相应的二进制位都为0,则该位的运算结果为0(假);否则为1(真)。即:0|0=0;0|1=1;1|0=1;1|1=1例如13|10的运算为:2022/12/241700001101(=13)(|)00001010(=10)00001111(=15)2.“按位或”运算(|)按位或”是指参加运算的两个数据,按对“按位或”运算的一大用途是经常用来对一个数据的某些位置1。【例11-7】将一个8位的二进制整数的低4位置1,高4位不变。2022/12/2418程序如下:#include<stdio.h>intmain(){charx=67;printf(“x初值为%d\n”,x);x=x|15;printf(“x|15运算后的值为%d\n”,x);return0;}程序运行结果为:x初值为67x|15运算后的值为79“按位或”运算的一大用途是经常用来对一个数据的某些位置1。【3.“按位异或”运算(^)“按位异或”是指参加运算的两个数据,按对应的二进制位分别进行“逻辑异或”运算。如果两个相应的二进制位为“异”(值不同),则该位的运算结果为1(真);否则运算结果为0(假)。即0^0=0;
0^1=1;1^0=1;1^1=0例如:13^10的运算为:2022/12/241900001101(=13)(^)00001010(=10)00000111(=7)3.“按位异或”运算(^)“按位异或”是指参加运算的两个数据“按位异或”运算有以下用途:(1)保留原值:与0进行“按位异或”运算,可保留原值。即:a^0=a。例如:
13^0的运算为:00001101(=13)
(^)00000000
结果为:000011012022/12/2420“按位异或”运算有以下用途:(1)保留原值:与0进行“按位(2)使特定位翻转:与1进行“按位异或”运算,可使操作数特定位进行翻转,即由0变1或者由1变0。2022/12/2421程序如下:#include<stdio.h>intmain(){charx=‘l’;printf(“‘l’=%d\n”,x);x=x^15;printf("x^15=%d\n",x);return0;}【例11-8】设字符x=‘l’,将其二进制数的高4位保留原样,低4位各位翻转。01101100(=108)(^)00001111(=15)01100011(=99)程序运行结果为:'l'=108x^15=99(2)使特定位翻转:与1进行“按位异或”运算,可使操作数特定(3)置零:每一个数与它自身进行“异或”运算,结果各位均为零。即:x^x=0。2022/12/24224.“按位取反”运算(~)按位取反”运算符“~”是唯一的一个单目位运算符,用来将一个二进制数的每一位取反,即将1(真)变0(假),将0(假)变1(真)。即~0=1;~1=0(3)置零:每一个数与它自身进行“异或”运算,结果各位均为零按位取反”运算常用来生成与系统实现无关的常数,以增加程序的可移植性。如要将变量x=103=(1100111)2最低6位置成0,其余位不变。用“按位与”运算实现,就需要考虑x在系统内存放的位数:如果x占2个字节,则需要执行:x=x&0xffc0如果x占4个字节,则需要执行:x=x&0xffffffc0但若果把表达式变为:x = x & ~0x3f整数x占2个字节还是占4个字节都能实现要求,大大增强了程序的可移植性。2022/12/2423按位取反”运算常用来生成与系统实现无关的常数,以增加程序的可11.2.2位移位运算符与运算
1.“左移”运算(<<)左移运算符“<<”是双目运算符,左移运算的一般形式为:运算对象<<左移位数。左移的作用是将一个数的各二进制位依次左移若干位(由左移位数给出),左移时,右端(低位)补0,左端(高位)移出的部分舍去。2022/12/242411.2.2位移位运算符与运算 1.“左移”运算(<<例如,假设以一个字节存一个整数,则无符号整型变量a=15,在执行a=a<<2后,a的值变为60。左移变化过程如下图:可见,左移1位相当于操作数乘以2,左移2位相当于操作数乘以4,…,左移n位相当于操作数乘以2n,此外,左移运算要比乘法快的多。但此结论只适用于该数左移时被溢出舍弃的高位中不包含1的情况。2022/12/2425000011110001111000111100左移一次左移一次例如,假设以一个字节存一个整数,则无符号整型变量a=15,在例如:若变量a=65,即二进制数(01000001)2时,左移一位时溢出的是0,变为(10000010)2,即130。而左移2位时,溢出的高位中包含1,a的值变为(00000100)2,即4,则不符合上述结论。【例11-9】输入两个数字符a和b,由a、b组合生成整数c(c用字符类型表示),并显示出来。生成规则是:a的低4位作为c的高4位,b的低4位作为c的低4位。2022/12/2426例如:若变量a=65,即二进制数(01000001)2时,左#include<stdio.h>intmain(){chara,b,c;while(1) {printf("Pleaseinputaandb:\n");scanf("%c,%c",&a,&b);if((a<='9')&&(a>='0')&&(b<='9')&&(b>='0'))break;}a=a<<4;b=b&0x0f;c=a|b;printf("c=%d\n",c);return0;} 2022/12/2427程序运行结果为:Pleaseinputaandb:1,9c=25#include<stdio.h>2022/12/16272.“右移”运算(>>)右移运算符“>>”是双目运算符,右移运算的一般形式为:运算对象>>右移位数右移的作用是将一个数的各二进制位依次右移若干位(由右移位数给出),右移时,右端(低位)移出的部分舍去,左端(高位)移入的二进制数分两种情况:对于无符号数和正整数,高位补0;对于负整数,有的系统高位补1,有的系统高位补0。补0的称为“逻辑右移”,即简单右移;补1的称为“算术右移”。具体情况需要查阅相应C编译程序用户手册。2022/12/24282.“右移”运算(>>)右移运算符“>>”是双目运算符,右移例如,占一个字节的无符号整型变量a=15,则a=a>>2后,a的值变为3(向下取整)。变化过程如图11-2所示。可见,右移1位相当于操作数除以2,右移2位相当于除以4,…,右移n位相当于操作数除以2n。但此结论只适用于该数为无符号数和正整数。2022/12/2429000011110000011100000011右移一次右移一次例如,占一个字节的无符号整型变量a=15,则a=a>>2后,【例11-10】取一个无符号整数a(16位)从右端开始的4~7位,重新构成一个数。分析:设a=(0000000011011001)2,其从右端开始的4~7位依次为1101,需要单独提取出来构成一个新数。2022/12/2430程序如下:#include<stdio.h>intmain(){unsigneda,b,c,d;printf(“Pleaseinputanoctalnumber:”);scanf("%d",&ab=a>>4c=~(~0<<4);d=b&c;printf("%d\n",d);return0;}程序运行结果为:Pleaseinputanoctalnumber:21713【例11-10】取一个无符号整数a(16位)从右端开始的4~11.2.3位运算赋值运算符在C语言中还提供了位运算符与赋值运算符组成的复合赋值运算符:&=、|=、^=、>>=和<<=。它们和复合赋值运算符的运算规则相似,结合方向从右向左,即把左边值与右边值位运算之后赋值给左边变量。例如:a&=0x19等价于a=a&0x19a<<=2等价于a=a<<22022/12/243111.2.3位运算赋值运算符在C语言中还提供了位运算符注意:不同类型的整数数据(即数据长度不同)在进行混合类型的位运算时,系统会按右端对齐原则进行处理,按数据长度大的数据进行处理,将数据长度小的数据左端补0或1。例如chara与intb进行位运算时,按int进行处理,chara转化为整型数据,并在左端补0。补位原则如下:(1)对于有符号数据:如果a为正整数,则左端补0,如果a为负数,则左端补1。(2)对于无符号数据:在左端补0。2022/12/2432注意:不同类型的整数数据(即数据长度不同)在进行混合类型的位位运算符优先级排列表2022/12/2433优先级位运算符优先级位运算符1~4^2<<、>>5|3&6&=、^=、|=、<<=、>>=位运算符优先级排列表2022/12/1633优先级位运算符11.3位运算应用程序举例【例11-11】从键盘输入一个整数,判断此数的奇偶性。分析:对一个二进制数而言,其最低一位为0时,就是偶数,否则为奇数。因此可利用“按位与”运算的保留指定位功能,将其二进制最后一位提取出来,加以判断是0还是1。2022/12/2434#include<stdio.h>intmain(){inta;printf("Pleaseinputanumber:");scanf("%d",&a);if((a&0x01)==0printf("%d是偶数!\n",a);elseprintf("%d是奇数!\n",a);return0;}程序运行结果为:Pleaseinputanumber:1515是奇数!11.3位运算应用程序举例【例11-11】从键盘输入一【例11-12】不用临时变量,交换两个字符变量的值。分析:这是一个经典的问题,交换变量的值,一般需要一个中间变量。然而利用“按位异或”运算中的位翻转特性,可以在没有中间变量的情况下实现整数间的互换。2022/12/2435#include<stdio.h>intmain(){chara=12,b=10;printf(“原数为a=%d,b=%d\n”,a,b);a=a^b;b=b^a;a=a^b;printf(“交换后为a=%d,b=%d\n”,a,b);return0;}程序运行结果为:原数为a=12,b=10交换后为a=10,b=12【例11-12】不用临时变量,交换两个字符变量的值。2022【例11-13】从键盘上输入一个十进制整数,统计该整数所对应的二进制数中1的个数(设整数占两个字节)。分析:统计一个整数m的二进制数中1的个数,可以利用“按位与”运算判断最后一位是否为1,然后再利用“右移”位运算,将m中的每一位依次移至最后一位进行上述判断,直至结束。2022/12/2436#include<stdio.h>intmain(){inti,count,m;printf("Pleaseinputm:");scanf("%d",&m);count=0;for(i=0;i<16;i++){if((m&0x01)==1)count++;m=m>>1;}printf("Numbersof1inmis%d\n",count);return0;}程序运行结果为:Pleaseinputm:15Numbersof1inmis4【例11-13】从键盘上输入一个十进制整数,统计该整数所对应【例11-14】循环移位。将十六进制数a进行循环右移,即a的二进制数的右端n位移到最左端n位。如:原数a=(12345678)16,循环右移4位后为(81234567)16.分析:这里不能直接使用>>运算符,因为,>>运算符在左面添0或添1不确定。所以要用左移与右移组合使用以达到目的。设整数a=0x12345678,内存占4个字节,循环右移n=4位(二进制位)。2022/12/2437#include<stdio.h>intmain(){unsigneda,b,c;intn;printf("请输入需要移动的数据:a=");scanf("%x",&a);printf("请输入需要移动的位数:n=");scanf("%d",&n);b=a<<(32-n);c=a>>n;c=c|b;printf(“%x\n”,c);return0;}程序运行结果为:请输入需要移动的数据:a=12345678请输入需要移动的位数:n=481234567【例11-14】循环移位。将十六进制数a进行循环右移,即a的11.4位
段计算机所能表示的信息的最小单位是一个字节,即8位。事实上在计算机用于过程控制、参数检测或数据通信领域时,控制信息往往只占一个字节中的一个或几个二进制位,例如,描述“真”或“假”时,通常用1表示“真”,0表示“假”,只需1位即可,而不需要占用8位甚至更多。为了有效的利用存储空间,提高效率,在C语言中,提供了一种特有的压缩信息的数据结构——位段。2022/12/243811.4位段计算机所能表示的信息的最小单位是一个字节位段(bit-field)是以位为单位来定义结构体中的成员变量所占的存储空间的长度。含有位段的结构体称为位段结构。位段结构也是一种结构体类型,与一般结构体在形式与用法上是很相近的。只不过其中含有以位为单位定义存储长度的整数类型位段成员。采用位段结构既节省存储空间,又可方便操作。2022/12/2439位段(bit-field)是以位为单位来定义结构体中的成员变11.4.1位段结构类型1.位段结构类型定义C语言中的位段是以“位”为单位来定义结构体中的成员长度的。其定义格式为:struct位段结构类型名{
类型说明符1位段名1:位段1占用位数;
/*最低位*/类型说明符2位段名2:位段2占用位数;
/*次低位*/ …;类型说明符n位段名n:位段n占用位数;};2022/12/244011.4.1位段结构类型1.位段结构类型定义2022/12/例如:
structpacked_flag{unsignedintf1:1;unsignedintf2:1;unsignedintf3:1;unsignedinttype:4;unsignedintindex:9;};2022/12/2441说明:该例中,定义了一个位段结构packed_flag。该结构定义了五个位段成员,均为unsignedint类型的。前三个位段依次叫做f1、f2和f3,各占1位;位段type占有4位;位段index占有9位。C编译器自动把上面的位段定义压缩在一起,这样结构packed_flag类型总共使用了16位,即2个字节。例如:2022/12/1641说明:该例中,定义了一个位位段定义注意事项(1)位段的类型只能是int或unsigned类型,不能是char型或者浮点型;(2)在位段结构中还可以定义无名位段。无名位段起位段之间的分隔作用。无名位段不能被访问,但是会占据空间。例如:2022/12/2442structpacked1{unsignedf1:4;unsignedf2:1;unsigned:2;
/*无名位段,起分隔作用*/unsignedf3:1;};f1f2f34121f2后面的无名位段占据2位,但其空间不用位段定义注意事项(1)位段的类型只能是int或unsigne(3)一个位段必须存储在同一存储单元,不能横跨两个存储单元。如果一个单元空间不够,则系统从下一个单元起存放该位段。(上述“存储单元”可能是一个字节,也可能是2个字节,视不同的编译系统而异)。假设现在的“存储单元”是2个字节,则下列位段定义:2022/12/2443假设现在的“存储单元”是2个字节,则下列位段定义:structpacked2{
unsignedf1:8;unsignedf2:4;unsignedf3:6;unsignedf4:2;};一个存储单元另一个存储单元(3)一个位段必须存储在同一存储单元,不能横跨两个存储单元。(4)长度为0的无名位段,可以强制其下一个位段到下一个存储单元存放。例如:structpacked3 {unsignedf1:4;
unsignedf2:2;Unsigned:0;
unsignedf3:2; };2022/12/2444一个存储单元另一个存储单元在这个位段定义中,f1、f2和f3共需要8位即可,但因为f2和f3之间的0长度位段的存在,f3只能存入下一个存储单元中。(4)长度为0的无名位段,可以强制其下一个位段到下一个存储单(5)在位段结构体中,不一定必须是位段成员,也可以包含非位段成员。例如:structpacked4 {unsignedf1:4;unsignedf2:4;unsignedf3:4;intn;
/*非位段成员*/ }data4;2022/12/2445(5)在位段结构体中,不一定必须是位段成员,也可以包含非位段11.4.2位段结构类型变量的定义与引用1.定义位段结构类型的变量位段结构类型变量的定义方法和其它结构类型变量定义方法一样。(1)先声明位段结构类型再定义变量。例如利用上面已经定义好的位段结构类型packed_flag来定义变量data的语句为:structpacked_flagdata;位段结构类型名
变量名;2022/12/244611.4.2位段结构类型变量的定义与引用1.定义位段结构类型(2)在声明位段结构类型的同时定义变量。其一般形式为:struct位段结构体名{成员列表}变量名列表;例如上述位段结构类型变量data的定义语句也可写成:2022/12/2447structpacked_flag{unsignedintf1:1;unsignedintf2:1;unsignedintf3:1;unsignedinttype:4;unsignedintindex:9;}data;(2)在声明位段结构类型的同时定义变量。其一般形式为:2022.位段成员的引用定义位段结构类型的变量后,就可以如引用一般结构体成员一样方便的引用位段成员:位段变量名.位段名例如由位段结构packed_flag定义了位段变量data后,各位段就可以有如下引用:data.f1=0;data.f2=1;data.index=data.f1+10;2022/12/24482.位段成员的引用2022/12/16483.位段引用时的注意事项(1)所赋值超过了位段所允许的最大范围,系统会自动取数的低位。(2)位段可以在表达式中被引用,并被系统自动转换成整型数。例如下面的表达式是合法的:data.f1+data.f2*2(3)位段可以以整型格式输出。例如: printf(“%d,%d”,data2.f1,data1.f2);2022/12/24493.位段引用时的注意事项2022/12/16494.位段引用举例【例11-15】请用三角形三边边长构造一个位段结构类型,并用其判断给定的三边边长能否构造成一个三角形。2022/12/2450#include<stdio.h>structtriangle{unsigneda:10;unsignedb:10;unsignedc:10;};intmain(){structtriangletr;printf(“sizeof(triangle)=%d\n”,sizeof(tr));tr.a=3;tr.b=4;tr.c=5;if(tr.a+tr.b>tr.c||tr.a+tr.c>tr.b||tr.b+tr.c>tr.a)printf(“Thethreesidesofatriangleare:a=%d,
b=%d,c=%d\n",tr.a,tr.b,tr.c);elseprintf("无法构成三角形\n");return0;}程序运行结果为:sizeof(triangle)=4Thethreesidesofatriangleare:a=3,b=4,c=54.位段引用举例【例11-15】请用三角形三边边长构造一个位2022/12/24511、有关数制的相关知识以及计算机中信息的计量单位。2、C语言6种位运算符以及具体运算规则:(1)按位与(&)运算:可以用来对数据清零、提取或保留二进制数指定位以及判断数据的奇偶性等;(2)按位或(|)运算经常用来将二进制数的某些位变为1;(3)按位异或(^)运算可以翻转特定位以及与0异或保留原值、与它自身异或置零;本章小结2022/12/16511、有关数制的相关知识以及计算机中信2022/12/2452(4)按位取反(~)运算常用来生成与系统实现无关的常数,以增加程序的可移植性;(5)左移(<<)运算中,左移n位相当于操作数乘以2n;(6)右移(>>)运算中,右移n位相当于操作数除以2n。3、位段——特殊形式的结构体,它是以“位”为单位来定义结构体中的成员长度的,既能够节省空间,又便于操作。注意本章节知识点!!2022/12/1652(4)按位取反(~)运算常用来生成与
程序设计技术基础程序设计技术基础第十一章位运算11.1数字系统、位和字节11.2位运算符与位运算11.3位运算应用程序举例11.4位
段2022/12/2454第十一章位运算11.1数字系统、位和11.1数字系统、位和字节11.1.1数字系统数制也称计数制,是用一组固定的符号和统一的规则来表示数值的方法。按进位的方法进行计数,称为进位计数制。如在日常生活中使用的十进制,在计算机中采用的二进制,以及八进制、十六进制等都是进位计数制。一种进位计数制包含一组数码符号和两个基本要素:基数和位权。2022/12/245511.1数字系统、位和字节11.1.1数字系统201.数码数码是指数制中表示基本数值大小的不同符号。例如十进制有10个数码:0、1、2、3、4、5、6、7、8、9。二进制有2个数码:0、1。八进制有8个数码:0、1、2、3、4、5、6、7。十六进制有16个数码:0~9和A、B、C、D、E、F。2022/12/24561.数码2022/12/1642.基数基数是指数制所使用数码的个数。例如,二进制的基数为2;十进制的基数为10。在运算中,当某一位上达到或超过基数大小时,就会向前进一。如十进制满十进一,二进制满二进一,十六进制则满十六进一。2022/12/24572.基数2022/12/1653.位权位权是指数制中每一固定位置对应的单位值。一个数据在某个位置上的值等于该数字与这个位置上的因子的乘积,而该因子的值是由所在位置相对于小数点的距离来确定的,这个因子就是位权,即各进位制中位权的值是基数的若干次幂。例如:十进制的123:1的位权是102=100,2的位权是101=10,3的位权是100=1;二进制中的1101,第一个1的位权是23=8,第二个1的位权是22=4,0的位权是21=2,第三个1的位权是20=1。2022/12/24583.位权2022/12/166任意的R进制数N按位权展开形式如下:其中:ri为计数制中任一个数码,R为基数。为了区分不同数制的数据,可以用括号加基数下标表示数据所属的数制。如:十进制数309.84的位权展开式为:(309.84)10=3×102+0×101+9×100+8×10-1+4×10-2二进制数11011.01的位权展开式为:(11011.01)2=1×24+1×23+1×21+1×20+1×2-22022/12/2459任意的R进制数N按位权展开形式如下:2022/12/16711.1.2位和字节在计算机中,表示信息的单位有位、字节、兆、吉等,它们是表示信息量大小的基本概念。1.位(bit)位,音译为“比特”,是计算机内构成信息的最小数据单位,即一个1或0。一般用小写字母“b”表示。一位二进制可表示21=2个信息,如:是或否,有或无,真与假等。2022/12/246011.1.2位和字节在计算机中,表示信息的单位有位、字节、2.字节(Byte)字节是计算机数据存储和处理信息的基本数据单位。简记为“B”规定1个字节为8位,即8个二进制位是一个字节。
1B=8b。2022/12/24612.字节(Byte)2022/12/169存储器的存储容量除了以位、字节为单位来度量外,还需要一些更大的单位,有KB、MB、GB、TB等度量单位:1KB=210B=1024B(K代表“千”)1MB=220B=210×210B=1024×1024B(M代表“兆”)1GB=230B=210×210×210B=1024×1024×1024B(G代表“吉”)1TB=240B=210×210×210×210B=1024×1024×1024×1024B(T代表“太”)2022/12/2462存储器的存储容量除了以位、字节为单位来度量外,还需要一些更大11.2位运算符与位运算C语言的位运算可以分为位逻辑运算与位移位运算,共计6种基本位运算符:注:(1)位运算符中,除~是单目运算符外,其余均为双目运算符;(2)运算量只能是整型或字符型的数据,不能为实型数据2022/12/2463运算符含义运算符含义&按位与|按位或︿按位异或~按位取反<<左移>>右移11.2位运算符与位运算C语言的位运算可以分为位逻辑运11.2.1位逻辑运算符与运算1.“按位与”运算(&)
“按位与”是指参加运算的两个数据,按对应的二进制位分别进行“逻辑与”运算。如果两个相应的二进制位都为1,则该位的运行结果为1(真);否则为0(假)。0&0=0;0&1=0;1&0=0;1&1=12022/12/246411.2.1位逻辑运算符与运算1.“按位与”运算(&)2例如:13&10=?00001101(=13)(&)00001010(=10)
00001000(=8)2022/12/2465例如:13&10=?2022/12/1613“按位与”运算有一些特殊的用途:2022/12/2466(1)清零:若想将某个二进制数的指定位清零,可将待清零位与0进行“按位与”运算,其余位与1进行“按位与”运算;若想将该数各位都清零,可使其与零进行“按位与”运算。【例11-6】将字符变量ch所占的字节单元清零。
“按位与”运算有一些特殊的用途:2022/12/1614(【例11-6】将字符变量ch所占的字节单元清零。程序如下:#include<stdio.h>intmain(){charch=67;printf("ch=%d\n",ch);ch=ch&0;printf("ch&0后ch=%d\n",ch);return0;}2022/12/2467程序运行结果为:ch=67ch&0后ch=0【例11-6】将字符变量ch所占的字节单元清零。程序如下:2(2)保留指定位:若想保留某个二进制数中的指定位。可将指定位与1进行“按位与”运算,其余位与0进行“按位与”运算即可实现。例如对一个十六位二进制整数a,若想要将其高八位清0,而保留其低八位。则进行:a&0000000011111111运算即可:0000000100110100(a=308)
(&)0000000011111111(=255)0000000000110100(=52)2022/12/2468(2)保留指定位:若想保留某个二进制数中的指定位。可将指定位2.“按位或”运算(|)按位或”是指参加运算的两个数据,按对应的二进制位分别进行“逻辑或”运算。如果两个相应的二进制位都为0,则该位的运算结果为0(假);否则为1(真)。即:0|0=0;0|1=1;1|0=1;1|1=1例如13|10的运算为:2022/12/246900001101(=13)(|)00001010(=10)00001111(=15)2.“按位或”运算(|)按位或”是指参加运算的两个数据,按对“按位或”运算的一大用途是经常用来对一个数据的某些位置1。【例11-7】将一个8位的二进制整数的低4位置1,高4位不变。2022/12/2470程序如下:#include<stdio.h>intmain(){charx=67;printf(“x初值为%d\n”,x);x=x|15;printf(“x|15运算后的值为%d\n”,x);return0;}程序运行结果为:x初值为67x|15运算后的值为79“按位或”运算的一大用途是经常用来对一个数据的某些位置1。【3.“按位异或”运算(^)“按位异或”是指参加运算的两个数据,按对应的二进制位分别进行“逻辑异或”运算。如果两个相应的二进制位为“异”(值不同),则该位的运算结果为1(真);否则运算结果为0(假)。即0^0=0;
0^1=1;1^0=1;1^1=0例如:13^10的运算为:2022/12/247100001101(=13)(^)00001010(=10)00000111(=7)3.“按位异或”运算(^)“按位异或”是指参加运算的两个数据“按位异或”运算有以下用途:(1)保留原值:与0进行“按位异或”运算,可保留原值。即:a^0=a。例如:
13^0的运算为:00001101(=13)
(^)00000000
结果为:000011012022/12/2472“按位异或”运算有以下用途:(1)保留原值:与0进行“按位(2)使特定位翻转:与1进行“按位异或”运算,可使操作数特定位进行翻转,即由0变1或者由1变0。2022/12/2473程序如下:#include<stdio.h>intmain(){charx=‘l’;printf(“‘l’=%d\n”,x);x=x^15;printf("x^15=%d\n",x);return0;}【例11-8】设字符x=‘l’,将其二进制数的高4位保留原样,低4位各位翻转。01101100(=108)(^)00001111(=15)01100011(=99)程序运行结果为:'l'=108x^15=99(2)使特定位翻转:与1进行“按位异或”运算,可使操作数特定(3)置零:每一个数与它自身进行“异或”运算,结果各位均为零。即:x^x=0。2022/12/24744.“按位取反”运算(~)按位取反”运算符“~”是唯一的一个单目位运算符,用来将一个二进制数的每一位取反,即将1(真)变0(假),将0(假)变1(真)。即~0=1;~1=0(3)置零:每一个数与它自身进行“异或”运算,结果各位均为零按位取反”运算常用来生成与系统实现无关的常数,以增加程序的可移植性。如要将变量x=103=(1100111)2最低6位置成0,其余位不变。用“按位与”运算实现,就需要考虑x在系统内存放的位数:如果x占2个字节,则需要执行:x=x&0xffc0如果x占4个字节,则需要执行:x=x&0xffffffc0但若果把表达式变为:x = x & ~0x3f整数x占2个字节还是占4个字节都能实现要求,大大增强了程序的可移植性。2022/12/2475按位取反”运算常用来生成与系统实现无关的常数,以增加程序的可11.2.2位移位运算符与运算
1.“左移”运算(<<)左移运算符“<<”是双目运算符,左移运算的一般形式为:运算对象<<左移位数。左移的作用是将一个数的各二进制位依次左移若干位(由左移位数给出),左移时,右端(低位)补0,左端(高位)移出的部分舍去。2022/12/247611.2.2位移位运算符与运算 1.“左移”运算(<<例如,假设以一个字节存一个整数,则无符号整型变量a=15,在执行a=a<<2后,a的值变为60。左移变化过程如下图:可见,左移1位相当于操作数乘以2,左移2位相当于操作数乘以4,…,左移n位相当于操作数乘以2n,此外,左移运算要比乘法快的多。但此结论只适用于该数左移时被溢出舍弃的高位中不包含1的情况。2022/12/2477000011110001111000111100左移一次左移一次例如,假设以一个字节存一个整数,则无符号整型变量a=15,在例如:若变量a=65,即二进制数(01000001)2时,左移一位时溢出的是0,变为(10000010)2,即130。而左移2位时,溢出的高位中包含1,a的值变为(00000100)2,即4,则不符合上述结论。【例11-9】输入两个数字符a和b,由a、b组合生成整数c(c用字符类型表示),并显示出来。生成规则是:a的低4位作为c的高4位,b的低4位作为c的低4位。2022/12/2478例如:若变量a=65,即二进制数(01000001)2时,左#include<stdio.h>intmain(){chara,b,c;while(1) {printf("Pleaseinputaandb:\n");scanf("%c,%c",&a,&b);if((a<='9')&&(a>='0')&&(b<='9')&&(b>='0'))break;}a=a<<4;b=b&0x0f;c=a|b;printf("c=%d\n",c);return0;} 2022/12/2479程序运行结果为:Pleaseinputaandb:1,9c=25#include<stdio.h>2022/12/16272.“右移”运算(>>)右移运算符“>>”是双目运算符,右移运算的一般形式为:运算对象>>右移位数右移的作用是将一个数的各二进制位依次右移若干位(由右移位数给出),右移时,右端(低位)移出的部分舍去,左端(高位)移入的二进制数分两种情况:对于无符号数和正整数,高位补0;对于负整数,有的系统高位补1,有的系统高位补0。补0的称为“逻辑右移”,即简单右移;补1的称为“算术右移”。具体情况需要查阅相应C编译程序用户手册。2022/12/24802.“右移”运算(>>)右移运算符“>>”是双目运算符,右移例如,占一个字节的无符号整型变量a=15,则a=a>>2后,a的值变为3(向下取整)。变化过程如图11-2所示。可见,右移1位相当于操作数除以2,右移2位相当于除以4,…,右移n位相当于操作数除以2n。但此结论只适用于该数为无符号数和正整数。2022/12/2481000011110000011100000011右移一次右移一次例如,占一个字节的无符号整型变量a=15,则a=a>>2后,【例11-10】取一个无符号整数a(16位)从右端开始的4~7位,重新构成一个数。分析:设a=(0000000011011001)2,其从右端开始的4~7位依次为1101,需要单独提取出来构成一个新数。2022/12/2482程序如下:#include<stdio.h>intmain(){unsigneda,b,c,d;printf(“Pleaseinputanoctalnumber:”);scanf("%d",&ab=a>>4c=~(~0<<4);d=b&c;printf("%d\n",d);return0;}程序运行结果为:Pleaseinputanoctalnumber:21713【例11-10】取一个无符号整数a(16位)从右端开始的4~11.2.3位运算赋值运算符在C语言中还提供了位运算符与赋值运算符组成的复合赋值运算符:&=、|=、^=、>>=和<<=。它们和复合赋值运算符的运算规则相似,结合方向从右向左,即把左边值与右边值位运算之后赋值给左边变量。例如:a&=0x19等价于a=a&0x19a<<=2等价于a=a<<22022/12/248311.2.3位运算赋值运算符在C语言中还提供了位运算符注意:不同类型的整数数据(即数据长度不同)在进行混合类型的位运算时,系统会按右端对齐原则进行处理,按数据长度大的数据进行处理,将数据长度小的数据左端补0或1。例如chara与intb进行位运算时,按int进行处理,chara转化为整型数据,并在左端补0。补位原则如下:(1)对于有符号数据:如果a为正整数,则左端补0,如果a为负数,则左端补1。(2)对于无符号数据:在左端补0。2022/12/2484注意:不同类型的整数数据(即数据长度不同)在进行混合类型的位位运算符优先级排列表2022/12/2485优先级位运算符优先级位运算符1~4^2<<、>>5|3&6&=、^=、|=、<<=、>>=位运算符优先级排列表2022/12/1633优先级位运算符11.3位运算应用程序举例【例11-11】从键盘输入一个整数,判断此数的奇偶性。分析:对一个二进制数而言,其最低一位为0时,就是偶数,否则为奇数。因此可利用“按位与”运算的保留指定位功能,将其二进制最后一位提取出来,加以判断是0还是1。2022/12/2486#include<stdio.h>intmain(){inta;printf("Pleaseinputanumber:");scanf("%d",&a);if((a&0x01)==0printf("%d是偶数!\n",a);elseprintf("%d是奇数!\n",a);return0;}程序运行结果为:Pleaseinputanumber:1515是奇数!11.3位运算应用程序举例【例11-11】从键盘输入一【例11-12】不用临时变量,交换两个字符变量的值。分析:这是一个经典的问题,交换变量的值,一般需要一个中间变量。然而利用“按位异或”运算中的位翻转特性,可以在没有中间变量的情况下实现整数间的互换。2022/12/2487#include<stdio.h>intmain(){chara=12,b=10;printf(“原数为a=%d,b=%d\n”,a,b);a=a^b;b=b^a;a=a^b;printf(“交换后为a=%d,b=%d\n”,a,b);return0;}程序运行结果为:原数为a=12,b=10交换后为a=10,b=12【例11-12】不用临时变量,交换两个字符变量的值。2022【例11-13】从键盘上输入一个十进制整数,统计该整数所对应的二进制数中1的个数(设整数占两个字节)。分析:统计一个整数m的二进制数中1的个数,可以利用“按位与”运算判断最后一位是否为1,然后再利用“右移”位运算,将m中的每一位依次移至最后一位进行上述判断,直至结束。2022/12/2488#include<stdio.h>intmain(){inti,count,m;printf("Pleaseinputm:");scanf("%d",&m);count=0;for(i=0;i<16;i++){if((m&0x01)==1)count++;m=m>>1;}printf("Numbersof1inmis%d\n",count);return0;}程序运行结果为:Pleaseinputm:15Numbersof1inmis4【例11-13】从键盘上输入一个十进制整数,统计该整数所对应【例11-14】循环移位。将十六进制数a进行循环右移,即a的二进制数的右端n位移到最左端n位。如:原数a=(12345678)16,循环右移4位后为(81234567)16.分析:这里不能直接使用>>运算符,因为,>>运算符在左面添0或添1不确定。所以要用左移与右移组合使用以达到目的。设整数a=0x12345678,内存占4个字节,循环右移n=4位(二进制位)。2022/12/2489#include<stdio.h>intmain(){unsigneda,b,c;intn;printf("请输入需要移动的数据:a=");scanf("%x",&a);printf("请输入需要移动的位数:n=");scanf("%d",&n);b=a<<(32-n);c=a>>n;c=c|b;printf(“%x\n”,c);return0;}程序运行结果为:请输入需要移动的数据:a=12345678请输入需要移动的位数:n=481234567【例11-14】循环移位。将十六进制数a进行循环右移,即a的11.4位
段计算机所能表示的信息的最小单位是一个字节,即8位。事实上在计算机用于过程控制、参数检测或数据通信领域时,控制信息往往只占一个字节中的一个或几个二进制位,例如,描述“真”或“假”时,通常用1表示“真”,0表示“假”,只需1位即可,而不需要占用8位甚至更多。为了有效的利用存储空间,提高效率,在C语言中,提供了一种特有的压缩信息的数据结构——位段。2022/12/249011.4位段计算机所能表示的信息的最小单位是一个字节位段(bit-field)是以位为单位来定义结构体中的成员变量所占的存储空间的长度。含有位段的结构体称为位段结构。位段结构也是一种结构体类型,与一般结构体在形式与用法上是很相近的。只不过其中含有以位为单位定义存储长度的整数类型位段成员。采用位段结构既节省存储空间,又可方便操作。2022/12/2491位段(bit-field)是以位为单位来定义结构体中的成员变11.4.1位段结构类型1.位段结构类型定义C语言中的位段是以“位”为单位来定义结构体中的成员长度的。其定义格式为:struct位段结构类型名{
类型说明符1位段名1:位段1占用位数;
/*最低位*/类型说明符2位段名2:位段2占用位数;
/*次低位*/ …;类型说明符n位段名n:位段n占用位数;};2022/12/249211.4.1位段结构类型1.位段结构类型定义2022/12/例如:
structpacked_flag{unsignedintf1:1;unsignedintf2:1;unsignedintf3:1;unsignedinttype:4;unsignedintindex:9;};2022/12/2493说明:该例中,定义了一个位段结构packed_flag。该结构定义了五个位段成员,均为unsignedint类型的。前三个位段依次叫做f1、f2和f3,各占1位;位段type占有4位;位段index占有9位。C编译器自动把上面的位段定义压缩在一起,这样结构packed_flag类型总共使用了16位,即2个字节。例如:2022/12/1641说明:该例中,定义了一个位位段定义注意事项(1)位段的类型只能是int或unsigned类型,不能是char型或者浮点型;(2)在位段结构中还可以定义无名位段。无名位段起位段之间的分隔作用。无名位段不能被访问,但是会占据空间。例如:2022/12/2494structpacked1{unsignedf1:4;unsignedf2:1;unsigned:2;
/*无名位段,起分隔作用*/unsignedf3:1;};f1f2f34121f2后面的无名位段占据2位,但其空间不用位段定义注意事项(1)位段的类型只能是int或unsigne(3)一个位段必须存储在同一存储单元,不能横跨两个存储单元。
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 监理部门绩效考核制度与实施指南
- 2025至2030中国医药零售行业供需状况及投资风险评估报告
- 2026中共北京市丰台区委党校面向应届毕业生招聘2人备考题库及参考答案详解(新)
- 2026吉林省高速公路集团有限公司招聘165人备考题库及参考答案详解(培优b卷)
- 2026江西省江投老年医养有限公司招聘9人备考题库附答案详解(轻巧夺冠)
- 2026广东广州市政务服务中心编外人员招聘备考题库含答案详解ab卷
- 快速入职培训课程教案模板
- 2026宁波甬科天使创业投资基金管理有限公司招聘1人备考题库附参考答案详解(完整版)
- 2026江苏徐州市国盛控股集团有限公司招聘18人备考题库带答案详解ab卷
- 2026岚图区域市场岗位社会招聘备考题库附答案详解(综合卷)
- 2025年黑龙江省事业单位招聘考试教师招聘考试政治学科专业知识试卷
- 2025年及未来5年中国膏药电商行业市场前景预测及投资战略研究报告
- 俄罗斯名曲赏析课件
- 肿瘤内科案例分析题库及答案
- 2025年辽宁沈阳事业单位招聘考试综合类专业能力测试试卷(财务类)
- TCSEM0024-2024智慧消防火灾防控系统建设要求
- T∕CECS 21-2024 超声法检测混凝土缺陷技术规程
- 基于BIM技术的装配式建筑施工管理与控制研究
- 临床科室每月运营分析报告
- 毛泽东思想和中国特色社会主义理论体系概论(大连海事大学)智慧树知到课后章节答案2023年下大连海事大学
- 保洁服务投标方案
评论
0/150
提交评论