第1章 词法“陷阱”
词法分析中的“贪心法”
当C编译器读入多个符号时,就需要做出判断:是将其作为两个分别的符号来对待还是合起来作为一个符号。
这时候就用到“贪心法”:从左到右一个一个字符的读入,如果可能组成一个符号,就继续往下读,然后继续判断,以此循环,直到读入的字符已经不可能组成一个有意义的符号。
例如a---b与a-- -b相同,而与a- --b不同
C中不允许嵌套注释!
第2章 语法“陷阱”
理解函数声明
遇到复杂的表达式不需要紧张,因为构造这类表达式其实都有一条简单的规则:按照使用的方式来声明。
任何C变量的声明都有两部分组成:类型和一组类似表达式的声明符(declarator)。
()的优先级比*高。
float *g(),(*h)();
所以g和h是不一样的,前者表示g函数的返回值是一个指向float的指针,而h则是一个函数指针。
一旦我们知道了如何声明一个给定类型的变量,那么该类型的类型转换符我们也就很容易得到了,我们只需要将声明中的变量名去掉即可。
例如float(*h)(),他的类型转换符为( float ( * ) () )。
有了这些基础,我们变可以来分析复杂的表达式,例如:(*void(*)())0)()
运算符的优先级问题
误用优先级导致的问题也不少了,最好是能够将优先级表背下来(但一般情况下做不到吧23333)
我们需要记住的最重要的两点:
① 任何一个逻辑运算符的优先级低于任何一个关系运算符
②移位运算符的优先级比算术运算符低,但比关系运算符要高
逻辑运算符(&& || ! )
关系运算符(>、>=、==、!=、<、<=)
移位运算符
三目条件运算符的优先级很低,逗号运算符的优先级最低
switch语句
在switch语句中,也许你最经常出现的问题就是忘记加上break语句。这看起来像一个劣势,但其实也是它的优势。因为如果是程序员特意去略去一个break,则可以表达出一些采用其他方式难以实现的程序控制结构。
假如你要设计一个程序来略去空白字符,你可以这样利用switch语句
case '\n':
case '\n':
case ' ':
.....
函数调用
假设f是一个函数
f()为一个函数调用语句
f则为计算函数f的地址
悬挂else引发的问题
要注意else和哪一个if相关联
COMMENTS | NOTHING