阅读《C陷阱与缺陷》的知识增量.docVIP

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

看完《C陷阱与缺陷》,忍不住要重新翻一下,记录一下与自己的惯性思维不符合的地方。记录的是知识的增量,是这几天的流量,而不是存量。 这本书是在ASCI C/C89订制之前写的,有些地方有疏漏。 第一章 词法陷阱 1.3 C语言中解析符号时使用贪心策略,如x+++++y将被解析为x++ ++ +y,并编译出错。 1.5 单引号引起的一个字符代表一个对应的整数,对于采用ASCII字符集的编译器而言,a与0141、97含义一致。 练习1.1 嵌套注释(如/*/**/*/)只在某些C编译器中允许,如gcc4.8.2编译时是不支持的。 第二章 语法陷阱 2.6 else始终与同一个括号内最近的未匹配的if结合 第三章 语义陷阱 3.1?int a[12][31]表示的是一个长度12的数组,每个元素是一个长度31的数组。 3.1 在需要指针的地方如果使用数组名来替换,那么数组名就被视为其下标为0的元素的指针,p = a的写法是非法的(gcc4.8.2只是警告)。 3.2 如何连接两个给出的字符串s、t?细节很重要,书中给出的答案如下: char *r,*malloc() //原文称不能直接声明一个s、t长度之和的数组,但c99可以声明变长数组,已经可以了 //记得要把长度加1 r = malloc(strlen(s) + strlen(t) +1); //必须判断内存是否分配成功 if(!r){ complain(); exit(1); } strcpy(r,s); strcat(r,t); ...... //完成之后一定要释放r free(r); 3.6 如何正确计算数组的边界?原则一,考虑最简单情况下的特例;原则二,仔细计算边界。 3.6 以下一段代码为何引起死循环?这是因为在内存地址递减时,a[10]就是i。 int i,a[10]; for(i = 1; i=10; i++) a[i] = 0; 3.6 边界的编程技巧:用第一个入界点和第一个出界点表示数值范围,即[low,high)。这样的效果是 取值范围的大小为两者之差。 若取值范围为空,则上界等于下界。 3.6?--n一般比n--执行速度更快。 3.7 运算符和||保证两个操作数从左至右求值,其他运算符的操作数求值顺序未定义。比如y[i] = x[i++]结果是未定义的。 3.9 如何检测a+b是否溢出? if(a+b 0)是不正确的,因为溢出时的行为是未定义的。正确的方法是将两者转换为unsigned型与INT_MAX比较 更巧妙的方法:if(a INT_MAX - b) 第四章 连接 4.2?int a若出现在所有函数体之外,则完成了声明与定义(分配存储空间)。而extern int a;只是声明,说明a的存储空间是在其他地方分配的,不是定义;因此必须在别的某个地方定义,同一个或不同的源文件均可。 4.3 static修饰符可以将一个函数或变量的作用域限制在一个源文件之内,不会与其他文件中的同名量发生冲突 4.5 声明与定义必须严格相同,而数组和指针是不同的。 4.6 如何避免声明与定义不符?遵守“每个外部对象只在一个地方声明”的规则即可。一般放在头文件中,所有用到此外部对象的源文件都要包括此头文件,定义此对象的文件也应该包括此头文件。 第五章 库函数 5.1 getchar()返回整数,不能把返回值赋值给char型变量再与EOF比较,因为EOF定义为-1,应该赋值给int型变量。 5.2 如果要对文件进行连续的read和write操作,则中间必须插入fseek函数调用。 5.3?setbuf(stdout, buf);可以强制将buf指向的char数组设为缓冲区,改变输出缓存大小。 5.3 书中使用缓冲区把stdin的内容复制到stdout的程序是错误的,因为缓冲区内容的写出直到缓冲区满或调用fflush才开始完成。可以把buf声明为静态的或者malloc在堆中,防止main函数结束后buf清空。 5..1 一个程序异常终止时,程序输出的最后一部分常常丢失,可以使用setbuf指向一个空指针作为缓冲区 5..2 putchar/getchar在stdio.h中使用宏实现,如果没有包括stdio.h,很大可能仍能运行,但是使用相应的函数代替,速度降低。 第六章 预处理器 6 宏只是对文本处理,是一个表达式,不是函数或语句 6.1 宏定义最好把每个参数和整个表达式使用括号括起来防止出错。 6.2 如果一个操作数在两个地方用到,将被求值两次。解决方案:操作数应该没有副作用;将宏实现为函数。 6.2 宏可能产生非常庞大的表达式。 6.3 宏的分号的使用很麻烦,assert的一种正确实现:#define assert(e) ((void)((e)||_asser

文档评论(0)

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

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

1亿VIP精品文档

相关文档