程序是由符号序列组成的,将程序分解成符号的过程称为“词法分析”。第一章考察在程序被词法分析器分解成各个符号的过程中可能出现的问题。
在C语言中,符号之间的空白(包括空格符、制表符和换行符)将被忽略。
1.1 = 不同于 ==
在使用过程中经常由于粗心而导致两者的误用,比如:
if ( x = y )
foo ( );
在准备使用“==”来判断是否相等时误使用了赋值操作,而导致了程序的错误。
1.2 & 和 | 不同于 && 和 ||
按位运算 & 和 | 常与逻辑运算符 && 和 || 之间调换,容易发生错误。这个在使用时要认真检查。
1.3 词法分析中的贪心法
C语言包含单字符符号如/、*等,也会包含一些多字符符号如/*、==等。当c编译器读入一个字符“/”后面又跟着一个字符“*”时,编译器必须做出判断,是将其当作两个单字符符号还是当做一个多字符符号?
对于这样的问题,有一个简单的规则:每一个符号应该包含尽可能多的字符。规则解释:从左到右一个字符一个字符的读入,如果该字符可以组成一个符号,那么再读入下一个字符,判断两个字符组成的字符串是否可能是一个符号的组成部分,如果可能,继续读入下一个字符,重复上述的判断,直到读入的字符组成的字符串已不再组成一个有意义的符号。这种方法称为“贪心法”,或者称为“大嘴法”。如:
a---b
与表达式:
a -- - b
的含义相同,而不同于
a - -- b
值得注意的一点,对于有没有空格也会影响字符的含义。如:
y = x/*p
p是一个指针,本意是x除以*p,而实际中/*组合在一块组成了一个符号,将后边的内容注释掉了。它有区别于:
y = x / *p
这样,加上空格后含义就发生了变化,如果想更为清楚就加上括号,表明谁跟谁是在一起的。
诸如此类的准二义性问题会经常出现,如果想要避免,就加上括号来让疑惑消除。
1.4 整形变量
如果一个整形变量的第一个字符是数字0,那么该常量常备视作八进制数。因此,10跟010的含义是截然不同的。当你在一些编译器中为了格式对齐无意中会将十进制数写成了八进数。而你写0129时(第一个字符是数字0,而后面出现了8与9),编译器就会提示错误。
1.5 字符与字符串
C语言中的单引号和双引号含义迥异,在某些情况下会将两者弄混。
单引号引起的字符实际上代表一个整数;双引号引起的是字符串,代表一个指向无名数组起始字符的指针,该数组被双引号之间的字符以及一个额外的二进制值为0的字符‘\0’初始化。
printf ( "Hello!\n" );
与
char hello[]={'H','e','l','l','o','!','\n',0};
printf(hello);
是等效的。
总结
这一章的内容相对容易造成失误的是第3节内容,这边要注意一下。第5节中双引号括起来的字符代表一个指针这个知识点要掌握一下。