第一章 词法“陷阱”
1.1 =不同于==
一般情况下,赋值运算符相对于比较运算符出现得更频繁,因此字符数比较少的符号=就作为了赋值运算符。
第一种情况:比较运算符==写成了赋值运算符=
while(c = ' ' || c == '\t' || c == '\n'){
c = getc(f);
}
本例中将==误写为=,因为赋值运算符=的优先级要低于逻辑运算符||,因此实际上是将
' ' || c == '\t' || c == '\n'
的值赋给了变量c。由于’ ‘的ASCII码值为32,因此上述表达式的值始终为1。
第二种情况:赋值运算符=写成了比较运算符==
if((filedesc == open(argv[i],0)) < 0)
error();
如果open函数执行成功,将返回0或者整数,如果执行失败,将返回-1。
上面的代码的本意是将open函数的返回值存储在变量filedesc中,然后判断其是否小于0来检查open是否执行成功。
当将赋值运算符=误写为比较运算符==之后,表达式的值为1或者0,所以函数error()始终都不会被执行。
1.2 &和| 与&&和||
&:表示按位与运算符
|:表示按位或运算符
&&:表示逻辑与运算符
||:表示逻辑或运算符
1.3 词法分析中的“贪心法”
所谓“贪心法”是指编译器在读取字符符号时,每一个字符应该包含尽可能多的字符。
即编译器从左到右一个字符一个字符地读入,如果该字符可能组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分,如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号。
例如:y = x/*p;
其中,/被编译器理解为一段注释的开始,编译器将不断地读入字符,直到出现/为止
1.4 整型常量
八进制表示:整型常量的第一个字符是数字0。
例如:10和010的含义是截然不同的:
10表示十进制数字10,010表示为十进制数字8。
因此,在实际的程序编写中,需要加0来进行字节对齐时应该特别注意。
1.5字符和字符串
C语言中,单引号引起的字符实际上代表一个整数,整数值对应于该字符的ASCII值;
双引号引起的字符串,代表的是一个指向无名数组起始字符的指针。
例如:‘a’表示的是字符a,其值为97;”a”表示的是字符串,其长度为2,结尾包含‘\0’。