读C陷阱和缺陷(三).docxVIP

  1. 1、本文档共4页,可阅读全部内容。
  2. 2、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
读C陷阱和缺陷(三)

读C陷阱和缺陷(C Traps and Pitfalls)(三)5、预处理器使用预处理器大致有两个方向的原因:(1)需要将某个变量在程序中所有实现的实例全部修改。这一条在C++中已用const定义变量替代了。(2)宏处理,来替代一个简单的函数,如putchar等。这一条在C++中已用内联函数替代了。宏只对文本起作用,提供了一种对组成C程序的字符进行变换的方式,面并不作用于程序中的对象。不能忽视宏定义的中空格;最好在宏定义中把每个参数都用括号括起来,同样把整个结果表达式也用括号括起来。此外宏可能会遇到的尴尬可能是在自增和自减中违背了原来的意思:#define abs(x) ((x)=0?(x):-(x))abs(x);//则可能出问题。宏不是语句。_FILE_,_LINE_是内建于处理器的宏,会自动扩展为所在文件的文件名和所处理代码行的行号。宏不是类型定义。#define T1 struct Me*typedef struct Me *T2;T1 a,b;=struct Me *a,b;T2 c,d;=struct Me *c,*d;6、Koenig和Moo语录对C++(1)所谓面向对象编程,就是使用继承和动态绑定机制编程。(2)用类来表示概念。(3)避免使用指针。(4)使用程序库。(5)避免重复。如果你发现自己在程序的两上不同部分里做了相同的事情,试着把两具部分合并到一个子过程中。如果你发现两个类的行为相近,试着把他们的相似部分统一集中到基类或模块中。7、可移植性错误1)如果c是一个字符变量,使用(unsigned)c就可得到与c等价的无符号数,这会失败的。因为在将字符c转换为无符号整数时,c将首先被转换成int型整数,面此时就可能非预期的结果(最高位会扩展,而字符的最高位是1还是0,则关系到扩展后是正数还是负数)。正确的方法是:使用语句(unsigned char)c,因为一个unsigned char类型在字符在转换成无符号整数时无需要首先转换为int型整数,而是直接进行转换。2)如果被移位的对象长度是n位,那么移位计数必须大小或等于0,而严格小于n。3)内存置0读取和存储指针为NULL的内存,可能发生灾难的后果,如下所示。int main(){char *p=NULL;cout*p;return 1;}4)险法运算时发生的截断q=a/b;r=a%b;在除法和取余关系中,最好维持如下的关系:A)q*b+r==aB)如果改变a的正负号,我们希望这会改变q的符号,但这不会影响q的绝对值。C)当b0时,希望r=0,且rb。余数在哈希表的索引中很有效。但是可惜的是,上面的三条是矛盾的,只能满足其中的两条。如3/2,q=1时,r=1;先满足第二条,(-3)/2,q=-1,则r=-1,则第三条不满足,如果先满足第三条,r=1,q=-2,则第二条又不满足了。大多数C编译器放弃了第三条。例如在取余中,h=n%HASHSIZE,此时h有可能负,如果我们不希望他是负的。可以这样写:h=n%HASHSIZE;If(h0) h+=HASHSIZE;而更好的做法是避免出现n的值为负这样的情形,并且声明n为无符号数。5)在移植问题中,一个重要的问题是防止不同机器上对数据的溢出。而这种情况多发生在负数变正数(n=-n)的情况下。因为计算机中用补码来表示数据,而补码中负数比正数大一,这样就有可能在由负数变成正数的情况下发生溢出。解决这个问题,有好几种方法:其一:把-n赋给一个unsigned long型的变量,然后对这个变量进行操作,但是我们不能对-n(设n为负数)求值,这样可能引起溢出。其二:在操作时使n始终是负数。下面是一个例子,始终用负数进行处理,以防止溢出:long atol(char *s)long r=0;int neg=0;switch(*s){case -:neg=1;case:+:s++;break;}while(*s=0*s=9){int n=*s++-0;if(neg)n=-n;r=r*10+n;}return r;}//6)表示字符:0+5和5的值相同,对ASCII和EBCDIC字符集是正确的,对符合ANSI C的实现也是正确的,但对某些机器对错,正确表示应当是:“0123456789”[n%10]这样来取字符。因为一个符串常量可以用来表示一个字符数组,所以在数组名出现的地方都可以用字符串常量来替换。7)测试工作考查最简单的特例。如数据全为空。考查边界处理情况。8)一个异常终止的程序可能没有机会来清空其输出缓冲区,解决方案是:强制不允许对输出进行缓冲,如下所示:setbuf(stdout,(char*)0);9)fprintf()函数会把格式字符串当做一个文件结构来处理,所以:fprintf(error\n)可能会灾难性的后果。正

文档评论(0)

xy88118 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档