在我们的程序中所谓的“符号”指的是程序的一个基本组成单元,其作用相当于一个句子中的单词。符号就是程序中的一个基本信息单元。而编译器的工作就是负责将程序分解为一个一个符号的部分,一般称为“词法分析器”。
在C语言中,符号之间的空白(包括空格符、制表符或换行符)将被忽略,因此语句
if (x > big) big = x;
可以分解为
if
(
x
>
big
)
big
=
x
;
1、=不同于==
在我们写程序的时候,经常将符号=写为==,这是一个非常隐蔽但又非常严重的错误,我们知道=是赋值运算符,而符号==是比较运算符。然而当程序员本意是作比较运算时,却可能无意中误写成了复制运算符。
比如下面的例子:
while (c = ' ' || c== '\t' || c == '\n')
c = getc (f);
由于程序员在比较字符' '和变量c时,误将比较运算符==写成了赋值运算符=。因为赋值运算符的优先级要低于逻辑运算符 ||,因此实际上是将一下表达式的值赋给了c:
‘ ’ || c== '\t' || c == '\n'
因为 ‘ ’不等于零(‘ ’的ASCII码值为32),那么无论变量c此前为何值,上述表达式的值得结果都是1,因此循环将一直进行下去直到整个文件结束。
2. 词法分析中的“贪心法”
C语言中既有单字符符号比如/、*、=等也有多字符运算符你如/*和==等,当多个运算符放在一起的时候,编译器就必须做出判断:是将其作为两个分别的符号对待还是合起来对待。C语言对这个问题的解决方案可以归纳为一个很简单的规则:每一个符号应该包含尽可能多的字符。也就是说,编译器将程序分解成符号的方法是,从左到右一个字符一个字符地读入,如果该字符可能组成一个字符,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个字符的组成部分;如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的字符。
3.整形常量
如果一个整形常量的第一个字符是数字0,那么该常量将被视作八进制数。因此C语言中的10和010的含义截然不同。因此我们这里需要注意的是有时候我们在上下文中为了格式对齐的需要,可能无意中将十进制数写成了八进制数。例如:
{
010,“hello”,
123,“world”
}
4.字符与字符串
用单引号引起的一个字符实际上代表一个整数,整数值对应于该字符在编译器采用的字符集中的序列值。
用双引号引起的字符串,代表的却是一个无名数组起始字符指针,该数组被双引号之间的字符以及一个额外的二进制为零的字符‘\0’初始化。