编译器中负责将程序分解为一个一个符号的部分,一般称为"词法分析器"。在C语言中,符号之间的空白(包括空格符、制表符或换行符)将被忽略。
1、=不同于==
C语言使用符号"="作为赋值运算符,符号"=="作为比较。赋值运算相对比较运算出现得更频繁,因此字符较少的符号"="就被赋予了更常用的含义——赋值操作。C语言中赋值符号被作为一种操作符对待,因而重复进行赋值操作可以很容易地书写,并且赋值操作还可以被嵌入到更大的表达式中。
这种使用上的便利性可能导致一个潜在的问题:当程序员本意是作为比较运算时,却可能无意中误写成了赋值运算。
if (x = y) break;
该句本意是要检查x是否等于y,而实际上是将y的值赋给了x,然后检查该值是否为零。
while(c = ‘ ‘ || c == ‘\t‘ || c == ‘\n‘) c = getc(f);
由于程序员在比较‘ ‘和变量c时误将比较运算符"=="写成了赋值运算符"="。因为赋值运算符"="优先级要低于逻辑运算符"||",因此实际上是将以下表达式的值赋给了c:
‘ ‘ || c == ‘\t‘ || c == ‘\n‘
因为‘ ‘不等于0(ASCII值为32),那么无论变量c此前为何值,上述表达式求值的结果都是1,循环一直进行下去直到整个文件结束。
我们应该显式地进行比较,不应该简单关闭警告选项。
if (x = y) foo();
应该写作:
if ((x = y) == !0) foo();
如果把赋值运算符误写成比较运算符,同样会造成混淆:
if ((filedesc == open(argv[i], 0)) < 0) error();
因为比较运算表达式的值只有0或者1,因此(filedesc == open(argv[i], 0))的值永远只会是0或1,不可能<0而执行到error()函数。
?
?
2、&和|不同于&&和||
?
3、词法分析中的"贪心法"
?
4、整型常量
?
5、字符与字符串