《c陷阱与缺陷》笔记

《c陷阱与缺陷》笔记

ID:34420515

大小:94.66 KB

页数:14页

时间:2019-03-06

《c陷阱与缺陷》笔记_第1页
《c陷阱与缺陷》笔记_第2页
《c陷阱与缺陷》笔记_第3页
《c陷阱与缺陷》笔记_第4页
《c陷阱与缺陷》笔记_第5页
资源描述:

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

1、第1章词法“陷阱” 1.1=不同于====为比较运算符,=为赋值运算符例: while(c=''

2、

3、c=='t'

4、

5、c=='')  c=getc(f);   本意是c和''比较,但错用成赋值符。这样的后果是将''

6、

7、c=='t'

8、

9、c==''这个表达式的值给了c,而使c=1。   同样:if((filedesc==open(argv[i],0))<0)error();   open的返回值和filedesc比较的结果只能是0或1,所以,error没有机会调用。但是,此时filedesc的值于open返回值无关,

10、编译器这里不会报错。容易被忽视,达不到检查效果。1.2&和

11、不同于&&和

12、

13、&和

14、均为按位运算符,而&&和

15、

16、均为逻辑运算符,不能混淆。1.3语法分析中的“贪心法”当C编译器读入一个字符后又跟了一个字符,那么编译器就必须做出判断:是将其作为两个分别的符号对待,还是合起来作为一个符号对待。C语言对这个问题的解决方案可以归纳为一个很简单的规则:每一个符号应该包含尽可能多的字符。a---b与a---b的含义相同,而与a---b的含义不同。1.4整型常量如果一个整形常量的第一个字符是数字0,那么该常量将被视作八进制数。因此,10和

17、010是完全不同的含义。此外书中还介绍了一些ANSIC不允许的做法,比如将8和9也作为八进制数字处理。1.5字符和字符串C语言中的单引号和双引号含义迥异,在某些情况下如果把两者弄混,编译器并不会检测报错,从而在运行是产生难以预料的结果。用单引号引起的一个字符实际上代表一个整数,整数值对应于该字符在编译器采用的字符集中的序列值。用双引号引起的字符串,代表的却是一个指向无名数字起始字符的指针,该数组被双引号之间的字符以及一个额外的二进制为零的字符''初始化。然而,某些C编译器对函数参数并不进行类型检查,特别是对printf函数

18、的参数。因此,如果用printf('');来代替正确的printf("");则会在程序运行的时候产生难以预料的错误,而不会给出编译器诊断信息。整型数(一般为16位或32为)的存储空间可以容纳多个字符(一般为8位),因此有个C编译器允许在一个字符常量(以及字符串常量)中包括多个字符。也就是说,用'yes'代替"yes"不会被该编译器检测到。后者的含义是“一次包括'y''e''s'以及空字符''的4个连续内存单元的首地址“。前者的含义并没有准确的进行定义,但大多数编译器理解为,“一个整数值,由'y''e''s'所代表的整数值按

19、照特定编译器实现中定义的方式组合得到“。(注:在BorlandC++v5.5和LCCv3.6中采取的做法是,忽略多余的字符,最后的整数值即第一个字符的整数值;而在VisualC++6.0和GCCv2.95中采取的做法是,依次用后一个字符覆盖前一个字符,最后得到的整数值即最后一个字符的整数值。)第2章:语法“陷阱”2.1理解函数声明(*(void(*)())0)();任何复杂表达式其实只有一条简单的规则:按照使用的方式来声明。任何C变量的声明都由两部分组成:类型以及一组类似表达式的声明符(declarator)。声明符从表面

20、上看与表达式有些类似,对它求值应该返回一个声明中给定类型的结果。因为声明符与表达式的相似,所以我们也可以在声明符中任意使用括号:float((f));这个声明的含义是:当对其求值时,((f))的类型为浮点类型,由此可以推知,f也是浮点类型。各种形式的声明还可以组合起来,就像在表达式中进行组合一样。因此,float*g(),(*h)()表示*g()与(*h)()是浮点表达式。因为()结合优先级高于*,*g()也就是*(g()):g是一个函数,该函数的返回值类型为指向浮点数的指针。同理,可以得出h是一个函数指针,h所指向函数的

21、返回值为浮点类型。一旦我们知道了如何声明一个给定类型的变量,那么该类型的类型转换符就很容易得到了:只需要把声明中的变量名和声明末尾的分号去掉,再将剩余的部分用一个括号整个“封装”起来即可。例如,因为下面的声明:float(*h)();表示h是一个指向返回值为浮点类型的函数的指针,因此,(float(*)())表示一个“指向返回值为浮点类型的函数的指针”的类型转换符。(*fp)();->(*0)();->(*(void(*)())0)();2.2运算符的优先级问题优先级最高者其实并不是真正意义上的运算符,包括:数组下标,函数

22、调用操作符各结构成员选择操作符。他们都是自左于右结合,因此a.b.c的含义是(a.b).c。()[]->.单目运算符的优先级仅次于前述运算符。在所有的真正意义上的运算符中,它们的优先级最高。单目运算符是自右至左结合。因此*p++会被编译器解释成*(p++)。!~++===(type)*&sizeof优先

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

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

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