陷进问题引入
#include <stdio.h> int main() { int a = 1; int b = 2; int* c = &b; printf("%d", a/*c); return 0; }
- 问: 上面代码输出什么?
有人说是0, 也有人说程序出错,说0的是想着a除(c), 说程序出错的是因为将 / 看做注释符号,因此程序出错。也就是当出现/这种多字符符号时,编译器是将其当成单字符‘ / ’ 和“ * ”两个字符,还是当成‘ / ’多字符。那如此有争议性的问题,是否有一个规则来解决其中的二义性呢?
这就是词法分析的贪心法,口语化也可以说作“大嘴法”。
贪心法的解释
编译器分辨符号的方法是:从左到右一个字符一个字符的读入如果这个字符可能组成一个符号,那么再读入下一个字符,判断已经读入的字符组成的字符串是否可能组成一个符号,如果可能,继续读入下一个字符,重复上述判断,直到读入的字符已经不再可能组成一个有意义的符号,才停止判断。
需要注意的是,除了字符串与字符常量,符号的中间不能有空白(空格符,制表符和换行符)。例如:
a---b
和 a -- - b
的含义相同。
a---b
和 a - -- b
的含义不相同。
所以,a/*c
会出现程序报错的情况,因为当出现 /* 后,后面一直没有接受到注释结束符号 */ 。
一个小题目
请问 a+++++b 的含义是什么?
按照贪心法的解释来推断,得到 ((a++)++) + b。那么放到编译器里是什么样的呢?
#include <stdio.h> int main() { int a = 1; int b = 2; printf("%d", a+++++b); return 0; }
运行后如下:
原因是(a++)的结果不能作为自增++的操作数,因此报错。
😄 创作不易,你的点赞和关注都是对我莫大的鼓励,再次感谢您的观看😄