c缺陷与陷阱(文字版).pdfVIP

  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陷阱与缺陷 C 语言:陷阱和缺陷 概述 C 语言像一把雕刻刀,锋利,并且在技师手中非常有用。和任何锋利的工具一样, C 会伤到那些不能掌握它的人。本文介绍C 语言伤害粗心的人的方法,以及如何避免伤害。 脚注[1] 0 简介 C 语言及其典型实现被设计为能被专家们容易地使用。这门语言简洁并附有表达力。但 有一些限制可以保护那些浮躁的人。一个浮躁的人可以从这些条款中获得一些帮助。 在本文中,我们将会看一看这些未可知的益处。这是由于它的未可知,我们无法为其进 行完全的分类。不过,我们仍然通过研究为了一个C 程序的运行所需要做的事来做到这些。 我们假设读者对C 语言至少有个粗浅的了解。 第一部分研究了当程序被划分为记号时会发生的问题。第二部分继续研究了当程序的记 号被编译器组合为声明、表达式和语句时会出现的问题。第三部分研究了由多 个部分组成、 分别编译并绑定到一起的 C 程序。第四部分处理了概念上的误解:当一个程序具体执行时 会发生的事情。第五部分研究了我们的程序和它们所使用的常 用库之间的关系。在第六部 分中,我们注意到了我们所写的程序也不并不是我们所运行的程序;预处理器将首先运行。 最后,第七部分讨论了可移植性问题:一个能 在一个实现中运行的程序无法在另一个实现 中运行的原因。 1 词法缺陷 编译器的第一个部分常被称为词法分析器(lexical analyzer )。词法分析器检查组成程序 的字符序列,并将它们划分为记号(token )一个记号是一个有一个或多个字符的序列,它 在语言被编译时具有 一个(相关地)统一的意义。在 C 中, 例如,记号-的意义和组成 它的每个独立的字符具有明显的区别,而且其意义独立于- 出现的上下文环境。 另外一个例子,考虑下面的语句: if(x big) big = x; 该语句中的每一个分离的字符都被划分为一个记号,除了关键字if 和标识符big 的两个实例。 事实上,C 程序被两次划分为记号。首先是预处理器读取程序。它必须对程序进行记号 划分以发现标识宏的标识符。它必须通过对每个宏进行求值来替换宏调用。最后,经过宏替 换的程序又被汇集成字符流送给编译器。编译器再第二次将这个流划分为记号。 在这一节中,我们将探索对记号的意义的普遍的误解以及记号和组成它们的字符之间的 关系。稍后我们将谈到预处理器。 1.1 = 不是 == 从Algol 派生出来的语言,如Pascal 和Ada ,用:=表示赋值而用=表示比较。而C 语言 则是用=表示赋值而用==表示比较。这是因为赋值的频率要高于比较,因此为其分配更短的 符号。 此外,C 还将赋值视为一个运算符,因此可以很容易地写出多重赋值(如a = b = c ), 并且可以将赋值嵌入到一个大的表达式中。 这种便捷导致了一个潜在的问题:可能将需要比较的地方写成赋值。因此,下面的语句 好像看起来是要检查x 是否等于y : if(x = y) foo(); 而实际上是将x 设置为y 的值并检查结果是否非零。在考虑下面的一个希望跳过空格、制表 符和换行符的循环: while(c == || c = \t || c == \n) c = getc(f); 在与\t进行比较的地方程序员错误地使用=代替了== 。这个“ 比较”实际上是将\t赋给 c,然 后判断 c 的(新的)值是否为零。因为\t 不为零,这个“ 比较”将一直为真,因此这个循环 会吃尽整个文件。这之后会发生什么取决于特定的实现是否允许一个程序读取超过文件尾部 的部分。如果允许,这 个循环会一直运行。 一些C 编译器会对形如e1 = e2的条件给出一个警告以提醒用户。当你趋势需要先对一 个变量进行赋值之后再检查变量是否非零时,为了在这种编译器中避免警告信息,应考虑显 式给出比较符。换句话说,将: if(x = y) foo(); 改写为: if((x = y) != 0) foo(); 这样可以清晰地表示你的意图。 1.2 和 | 不是 和 || 容易将==错写为=是因为很多其他语言使用=表示比较运算。其他容易写错的运算符还 有和,或|和||,这主要是因为 C 语言中的和|运算符于其他语言中具有类似功能的运 算符 大为不同。我们将在第4节中贴近地观察这些运算符。 1.3 多字符记号 一些C 记号,如/ 、*和=只有一个字符。而其他一些C 记号,如/*和

文档评论(0)

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

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

1亿VIP精品文档

相关文档