c陷阱与缺陷总结-词法分析中的”贪心法“

C语言中分为单字符符号如 /、*、和 =,还有多字符符号如 /* 和 == 。

当C编译器读入一个字符 '/' 后跟又跟了一个字符 ’*‘,那么编译器就必须做出判断:是将其作为两个分别的符号对待,还是合起来作为一个符号对待。

C语言对这个问题的解决方案可以归纳为一个简单的规则:每一个符号应该包含尽可能多的字符。也就是说,编译器将程序分解成符号的方法是,从左到右一个字符一个字符读入,如果该字符可能组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号。这个处理策略有时被称为“贪心法”或者"大嘴法”。

需要注意:除了字符串与字符常量,符号的中间不能嵌有空白(空格符、制表符和换行符)。

表达式
a--b
与表达式
a -- - b
的含义相同而与
a - -- b
的含义不同。
下面的语句的本意似乎是用x除以p所指向的值,把所得的商再赋给y:
y = x/*p; 
而实际上,"/*" 被编译器理解为一段注释的开始,编译器将不断地读入字符,直到"*/"出现为止。
也就是说,该语句直接将x的值赋给y,根本不会顾及到后面出现的p。将上面的语句重写如下:
y = x / *p; // p指向除数
或者更加清楚一点,写作:
y= x/(*p);
这样得到的实际效果才是语句注释所表示的原意。
练习 a+++++b的含义是什么?
上式唯一有意义的解析方式是 a ++ + ++ b
可是根据“贪心法” 规则,上式可被分解为:
a ++ ++ + b
这个式子从语法上来说是不正确的,它等价于:
((a++)++) + b
但是,a++结果是右值,不能继续进行++操作。所以会出现编译错误。
关于++i++ 编译错误?
在++i++中,由于两个原因:
一编译器贪心法,那么划分成前缀++和后缀++。
二是操作符的优先级,后缀++的优先级大于前缀++
那么++i++的结果就是:++(i++),由于i++返回值为右值,所以无法进行前缀++操作,编译错误。
参考:C++ 操作符优先级


你可能感兴趣的:(c陷阱与缺陷总结-词法分析中的”贪心法“)