c语言缺陷与陷阱(笔记)

c语言缺陷与陷阱(笔记)

ID:3913908

大小:249.19 KB

页数:36页

时间:2017-11-25

c语言缺陷与陷阱(笔记)_第1页
c语言缺陷与陷阱(笔记)_第2页
c语言缺陷与陷阱(笔记)_第3页
c语言缺陷与陷阱(笔记)_第4页
c语言缺陷与陷阱(笔记)_第5页
资源描述:

《c语言缺陷与陷阱(笔记)》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、[修订说明]改正了文中的大部分错别字和格式错误,并对一些句子依照中文的习惯进行了改写。[译序]那些自认为已经“学完”C语言的人,请你们仔细读阅读这篇文章吧。路还长,很多东西要学。我也是……[概述]C语言像一把雕刻刀,锋利,并且在技师手中非常有用。和任何锋利的工具一样,C会伤到那些不能掌握它的人。本文介绍C语言伤害粗心的人的方法,以及如何避免伤害。[内容]0简介1词法缺陷1.1=不是==1.2&和

2、不是&&和

3、

4、1.3多字符记号1.4例外1.5字符串和字符2句法缺陷2.1理解声明2.2运算符并不总是具有你所想象的优先级2.3

5、看看这些分号!2.4switch语句2.5函数调用2.6悬挂else问题3连接3.1你必须自己检查外部类型4语义缺陷4.1表达式求值顺序4.2&&、

6、

7、和!运算符4.3下标从零开始4.4C并不总是转换实参4.5指针不是数组4.6避免提喻法4.7空指针不是空字符串4.8整数溢出4.9移位运算符5库函数5.1getc()返回整数5.2缓冲输出和内存分配6预处理器6.1宏不是函数6.2宏不是类型定义7可移植性缺陷7.1一个名字中都有什么?7.2一个整数有多大?7.3字符是带符号的还是无符号的?7.4右移位是带符号的还是无符号的?

8、7.5除法如何舍入?7.6一个随机数有多大?7.7大小写转换7.8先释放,再重新分配7.9可移植性问题的一个实例8这里是空闲空间参考脚注0简介C语言及其典型实现被设计为能被专家们容易地使用。这门语言简洁并附有表达力。但有一些限制可以保护那些浮躁的人。一个浮躁的人可以从这些条款中获得一些帮助。在本文中,我们将会看到这些未可知的益处。正是由于它的未可知,我们无法为其进行完全的分类。不过,我们仍然通过研究为了一个C程序的运行所需要做的事来做到这些。我们假设读者对C语言至少有个粗浅的了解。第一部分研究了当程序被划分为记号时会发生的

9、问题。第二部分继续研究了当程序的记号被编译器组合为声明、表达式和语句时会出现的问题。第三部分研究了由多个部分组成、分别编译并绑定到一起的C程序。第四部分处理了概念上的误解:当一个程序具体执行时会发生的事情。第五部分研究了我们的程序和它们所使用的常用库之间的关系。在第六部分中,我们注意到了我们所写的程序也许并不是我们所运行的程序;预处理器将首先运行。最后,第七部分讨论了可移植性问题:一个能在一个实现中运行的程序无法在另一个实现中运行的原因。1词法缺陷编译器的第一个部分常被称为词法分析器(lexicalanalyzer)。词法

10、分析器检查组成程序的字符序列,并将它们划分为记号(token)一个记号是一个由一个或多个字符构成的序列,它在语言被编译时具有一个(相关地)统一的意义。在C中,例如,记号->的意义和组成它的每个独立的字符具有明显的区别,而且其意义独立于->出现的上下文环境。另外一个例子,考虑下面的语句:if(x>big)big=x;该语句中的每一个分离的字符都被划分为一个记号,除了关键字if和标识符big的两个实例。事实上,C程序被两次划分为记号。首先是预处理器读取程序。它必须对程序进行记号划分以发现标识宏的标识符。它必须通过对每个宏进行求

11、值来替换宏调用。最后,经过宏替换的程序又被汇集成字符流送给编译器。编译器再第二次将这个流划分为记号。在这一节中,我们将探索对记号的意义的普遍的误解以及记号和组成它们的字符之间的关系。稍后我们将谈到预处理器。1.1=不是==从Algol派生出来的语言,如Pascal和Ada,用:=表示赋值而用=表示比较。而C语言则是用=表示赋值而用==表示比较。这是因为赋值的频率要高于比较,因此为其分配更短的符号。此外,C还将赋值视为一个运算符,因此可以很容易地写出多重赋值(如a=b=c),并且可以将赋值嵌入到一个大的表达式中。这种便捷导致

12、了一个潜在的问题:可能将需要比较的地方写成赋值。因此,下面的语句好像看起来是要检查x是否等于y:if(x=y)foo();而实际上是将x设置为y的值并检查结果是否非零。再考虑下面的一个希望跳过空格、制表符和换行符的循环:while(c==''

13、

14、c='t'

15、

16、c=='')c=getc(f);在与't'进行比较的地方程序员错误地使用=代替了==。这个“比较”实际上是将't'赋给c,然后判断c的(新的)值是否为零。因为't'不为零,这个“比较”将一直为真,因此这个循环会吃尽整个文件。这之后会发生什么取决于特定的实现

17、是否允许一个程序读取超过文件尾部的部分。如果允许,这个循环会一直运行。一些C编译器会对形如e1=e2的条件给出一个警告以提醒用户。当你确实需要先对一个变量进行赋值之后再检查变量是否非零时,为了在这种编译器中避免警告信息,应考虑显式给出比较符。换句话说,将:if(x=y)foo();改写为:if((x=y

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。