C语言编程要点字符串操作_第1页
C语言编程要点字符串操作_第2页
C语言编程要点字符串操作_第3页
C语言编程要点字符串操作_第4页
C语言编程要点字符串操作_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C语言编程要点第10章位(bit)和字节(byte)第10章位(bit)和字节(byte)位指的是二进制系统中的一位,它是最小的信息单位。位的用处可以从两方面去分析:第一,计算机对位的值可以有任意多种解释,例如表示"yes'或"no",或者表示磁盘是否已插入驱动器,或者表示某个鼠标键是否被按下;第二,将若干位的值连接起来后,就可以表示更复杂的数据,而且每增加一位,可以表示的可能的值的数目就会增加一倍。换句话说,一位可以表示两种可能的值,即“O和“1;”两位可以表示2M或4种可能的值,即“00:“01,”“1丽“11;”类似地,三位可以表示2X2应或8种可能

2、的值。对计算机来说,位的这种特性既是最有力的支持因为很复杂的数据(例如本书内容)可以被分解为位的表示后存储起来,又是最大的限制因为在现实生活中许多事物的值是不精确的,这样的值无法用数目有限的若干位来表示。程序员始终必须清楚每一项数据需要用多少位来表示。因为位作为单位太小,所以为了方便起见,大多数计算机所处理的信息单位是被称为字节的位块。字节是大多数计算机中最小的可寻址的信息单位,这意味着计算机给每一个字节的信息都赋予一个地址,并且一次只能存取一个字节的信息。一个字节中的位的数目可以是任意的,并且在不同的计算机中可以不同。最常见的情况是每个字节中有8位,即可以存放256个不同的值。8位这样的长度

3、非常适合于存放表示ASCII(theAmericanStandardCodeforInformationInterchange)字符的数据。下述程序可以显示空格符以后的ASCII字符和PC机的图形字符集:#include<stdio.h>voidmain(void);voidmain()/"DisplayASCIIcharset"/unsignedcharspace=''/*StartwithSPACEchar=8bitsonly*/intctr=0;printf("ASCIICharactersn")?printf(&quo

4、t;=n");for(ctr=O;ctr+space<256;ctr+)printf("%c",ctr+space);printf("n");请注意,变量ctr必须是int类型,而不能是char类型,因为char类型只含8位,只能存放从0至255之间的值(signedchar类型只能存放从-128至127之间的值)。如果ctr是char类型,它就永远不会存放256或比256更大的值,程序也就永远不会结束。此外,如果你在非PC机的计算机上运行上述程序,那么程序所打印的非ASCII字符可能会导致乱屏。因为计算机是以字节块的方式工作的,所以大多

5、数程序也以这种方式工作,有时,考虑到要存放的数据项的数目,或者移动每一位的信息所需的时间,节省内存空间就显得很有必要。这时,我们通常会用少于一个字节的空间来存放那些只有少数可能值的数据,这也就是本章要讨论的主要内容10.1. 用什么方法存储标志(flag)效率最高?标志的作用是对程序执行过程中的两种或更多种选择作出决定。例如,在执行MS-DOS的dir命令时,可以用“w”标志使该命令在屏幕上显示若干列文件名而不是每行只显示一个文件名。在35中你可以看到另外一个例子,该例通过一个标志从两种可能类型中选择一种在一个联合中使用。因为一个标志一般只有少数几个(通常是两个)值,所以,为了节省内存空间,通

6、常不会将一个标志存放在一个属于它自己的int或char类型中。存储标志值的效率是存储空间和存取速度之间的一种折衷。存储空间利用效率最高的存储方法是用数目足够的位来存储标志值的所有可能值,但大多数计算机不能直接寻址内存中单独的一位,因此标志值要从存放它的字节中提取。存取速度最快的存储方法是将每个标志值都存放到一个属于它自己的整型变量中,但是,当一个标志只需要一位存储空间而变量的长度为32位时,那么其余的31位就全部浪费掉了,因此这种方法的存储空间利用效率非常低。如果标志的数目不多,那么使用哪种存储方法是没有关系的。如果标志的数目很多,那么最好将它们压缩存储在一个字符数组或整型数组中。这时,需要通

7、过一种被称为位屏蔽(bitmasking)的过程来提取这些标志值,即屏蔽掉不需要的位,只处理所需的位。有时,为了节省存储空间,可能会将一个标志和另外一个值存放在一起。例如,如果一个整型的值小于整型所能表示的最大值,那么就可用它的高阶位来存放标志;如果某些数据总是2或4的倍数,那么就可用它的低阶位来存放标志。在35的例子中,就使用了一个指针的低阶位来存放一个标志,该标志的作用是从两种可能的类型中选择一种作为该指针所指向的对象类型。请参见:102什么是“位屏蔽(bitmasking)”?103位域(bitfields)是可移植的吗?104移位和乘以2这两种方式中哪一种更好?10.2. 什么是“位屏

8、蔽(bitmasking)”?位屏蔽的含义是从包含多个位集的一个或一组字节中选出指定的一(些)位。为了检查一个字节中的某些位,可以让这个字节和屏蔽字(bitmask)进行按位与操作(C的按位与运算符为&)屏蔽字中与要检查的位对应的位全部为1,而其余的位(被屏蔽的位)全部为0。例如,为了检查变量flags的最低位,你可以让flags和最低位的屏蔽字进行按位与操作:flags&1;为了置位所需的位,可以让数据和屏蔽字进行按位或操作(C的按位或运算符为|)。例如,你可以这样置位flags的最低位:flags=flags|1;或者这样:flags|=1;为了清除所需的位,可以让数据和对

9、屏蔽字按位取反所得的值进行按位与操作。例如,你可以这样清除flags的最低位:flags=flags&1;或者这样:flags&=1;有时,用宏来处理标志会更方便,例102中的程序就是通过一些宏简化了位操作。例102能使标志处理更方便的宏/*BitMasking*/*Bitmaskingcanbeusedtoswitchacharacterbetweenlowercaseanduppercase*/( 1U ?(N) )( (N) | = (F) )( (N) &= - (F) )#defineBIT_POS(N)#defineSET_FLAG(N,F)#defineC

10、LR_FLAG(N,F)#define BIT_RANGE(N,M)#define BIT_SHIFTL(B,N)#define BIT_SHIFTR(B,N)#define SET_MFLAG(N,F,V)#define CLR_MFLAG(N,F)#define GET_MFLAG(N,F)(BIT_POS(M)+1-(N)-1<<(N)(unsigned)(B)?(N)(unsigned)(B)?(N)(CLR_FLAG(N,F),SET_FLAG(N,V)(N)&=(F)(N)&(F)#include<stdio.h>voidmain()unsi

11、gnedcharascii_char='A'/*char=8bitsonly*/inttest_nbr=10;printf("Startingcharacter=%cn",ascii_char);/"The5thbitpositiondeterminesifthecharacterisuppercaseorlowercase.5thbit=0-Uppercase5thbit=1-Lowercase*/printf("nTurn5thbiton=%cn",SET_FLAG(ascii_char,BIT_POS(5);printf(

12、"Turn5thbitoff=%cnn",CLR_FLAG(ascii_char,BIT_POS(5);printf("Lookatshiftingbitsn");printf("=n");printf("Currentvalue=%dn",test_nbr)iprintf("Shiftingonepositionleft=%dn",test_nbr=BIT_SHIFTL(test_nbr,1);printf("Shiftingtwopositionsright=%dn",B

13、IT_SHIFTR(test_nbr,2);宏BIT_POS(N)能返回一个和N指定的位对应的屏蔽字(例如BIT_POS(O)和BIT_POS(1)分别返回最低位和倒数第二位的屏蔽字),因此你可以用#defineA_FLAGBIT_POS(12)#defineA_FLAGBIT_P0S(13)代替#defineA_FLAG4096#defineA_FLAG8192这样可以降低出错的可能性。宏SET_FLAG(N,F)能置位变量N中由值F指定的位,而宏CLR_FLAG(N,F)则刚好相反,它能清除变量N中由值F指定的位。宏TST_FLAG(N,F)可用来测试变量N中由值F指定的位,例如:if(T

14、ST_FLAG(flags,A_FLAG)/*dosomething*/;宏BIT_RANGE(N,M)能产生一个与由N和M指定的位之间的位对应的屏蔽字,因此,你可以用# defineFIRST_OCTAL_DIGITBIT_RANGE(0,2)/*111"/* 111000*/# defineSECOND-OCTAL-DIGITBIT-RANGE(3,5)代替#define FIRST_OCTAL_DIGIT 7/*111*/#defineSECOND_OCTAL_DIGIT56/*111000*/这样可以更清楚地表示所需的位。宏BIT_SHIFT(B,N)能将值B移位到适当的区域

15、(从由N指定的位开始)。例如,如果你用标志C表示5种可能的颜色,你可以这样来定义这些颜色:#defineC_FLAGBIT-RANGE(8,10)/*11100000000*/*hereareallthevaluestheCflagcantakeon*/# defineC_BLACKBIT-SHIFTL(0,8)/*ooooooooooo*/# defineC-REDBIT_SHIFTL(1,8)/*00100000000*/# defineC-GREENBIT_SHIFTL(2,8)/*01000000000*/# defineC-BLUEBIT-SHIFTL(3,8)/*011000000

16、00*/# defineC_WHITEBIT-SHIFTL(4,8)/*10000000000*/# defineC-ZEROC-BLACK# defineC-LARGESTC-WHITE/*Atrulyparanoidprogrammermightdothis*/#ifC_LARGEST>C_FLAGCauseanerrormessage.TheflagC_FLAGisnotbigenoughtoholdallitspossiblevalues.#endif/*C_LARGEST>C_FLAG*/宏SET_MFLAG(N,F,V)先清除变量N中由值F指定的位,然后置位变量N中由值

17、V指定的位。宏CLR_MFLAG(N,F)的作用和CLR_FLAG(N,F)是相同的,只不过换了名称,从而使处理多位标志的宏名字风格保持一致。宏GET_MFLAG(N,F)能提取变量N中标志F的值,因此可用来测试该值,例如:if(GET_MFLAG(flags,C_FLAG)=C_BLUE)/*dosomething*/;注意:宏BIT_RANGE()和SET_MFLAG()对参数N都引用了两次,因此语句SET_MFLAG(*x+,C_FLAG,C_RED);的行为是没有定义的,并且很可能会导致灾难性的后果。请参见:10.1用什么方法存储标志(flag)效率最高?103位域(bitfields

18、)是可移植的吗?10.3. 位域(bitfields)是可移植的吗?位域是不可移植的。因为位域不能跨越机器字,而且不同计算机中的机器字长也不同,所以一个使用了位域的程序在另一种计算机上很可能无法编译。假设你的程序能在另一种计算机上编译,将位分配给位域时所遵循的顺序仍然是没有定义的。因此,不同的编译程序,甚至同一编译程序的不同版本所产生的代码,很可能无法在由原来的编译程序所生成的数据上工作。通常应该避免使用位域,除非计算机能直接寻址内存中的位并且编译程序产生的代码能利用这种功能,并且由此而提高的速度对程序的性能是至关重要的。请参见:10 .1用什么方法存储标志(flag)效率最高?11 2什么是

19、“位屏蔽(bitmasking)”?10.4. 移位和乘以2这两种方式中哪一种更好?不管你采用哪种方式,任何合格的优化编译程序都会产生相同的代码,因此你可以采用使程序的上下文更易读的那种方式。你可以用DOSWindows上的CODEVIEW或UNIX机上的反汇编程序(通常被称为"dis”)这样的工具来查看下述程序的汇编代码:例104乘以2和左移一位经常是相同的voidmain()unsignedinttest_nbr=300;test_nbr*=2;test_nbr=300;test_nbr<<=1;请参见:10. 1用什么方法存储标志(flag)效率最高?10.5. 什

20、么是高位字节和低位字节?通常我们从最高有效位(mostsignificantdigit)开始自左向右书写一个数字。在理解有效位这个概念时,可以想象一下你的支票数额的第一位增加1和最后一位增加1之间的巨大区别,前者肯定会让你喜出望外。计算机内存中一个字节的位相当于二进制数的位,这意味着最低有效位表示1,倒数第二个有效位表示2X1或2,倒数第三个有效位表示2X2X1或4,依此类推。如果用内存中的两个字节表示一个16位的数,那么其中的一个字节将存放最低的8位有效位,而另一个字节将存放最高的8位有效位,见图105。存放最低的8位有效位的字节被称为最低有效位字节或低位字节,而存放最高的8位有效位的字节被称为最高有效位字节或高位字节。高位字节低位字节1514131211109.8.7.6.5.4.3.2.1.0.图10.5双字节整数中的位请参见:10. 616位和32位的数是怎样存储的10.6. 16位和32位的数是怎样存储的?一个16位的数占两个字节的存储空间,即高位字节和低位字节(见105中的介绍

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论