鱼C论坛

 找回密码
 立即注册
查看: 1991|回复: 1

[技术交流] C编译器的嵌套注释思考

[复制链接]
发表于 2016-12-31 23:37:56 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
最近在《C陷阱与缺陷》中发现一个有意思的问题:
某些C编译器允许嵌套注释。请写一个测试程序,要求:无论是对允许嵌套注释的编译器,还是对不允许嵌套注释的编译器,该程序都能正常通过编译(无错误消息出现),但是这两种情况下程序执行的结果却不相同。

我感觉这道题对词法的分析挺有意思的,你是不是有什么方法可以解答?

在预处理阶段,C预处理器会剔除所有出现在“/*”和“*/”之间的内容(包括这对记号本身),所以在接下来传送到C编译器的代码文件里是不会出现任何注释内容的。

当然有不少的编译器是不会支持嵌套注释的。 /*/* */*/这样是行不通的,这样编译去遇到的第一个*/就会结束,认为/*/**/这已经构成了一个完整的注释。

/*/**/“1*/”/*0“/**/

你怎么看上面这个?

这个的解决主要是利用了编译器词法分析中的”贪心法“
注解:贪心法就是编译器将程序分解成符号的方法是,从左到右一个字符一个字符地进行读入,如果该字符可能组成一个符号,那么再读入下一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一个字符,重复上述操作,直到读入的字符组成的字符串已经不再可能组成一个有意义的符号,这个处理策略被称为”贪心法“,或者更通俗的说”大嘴法“

那么我们再来看这个
/*/**/“0*/”/*1“/**/
你会怎么处理,这一行被编译器处理后会是什么样子?

好吧,直接来一起分析吧。

支持嵌套注释的编译器:
  /*/**/“0*/     ”/*1“     /**/   
  得到的结果是:”/*1“

不支持嵌套注释的编译器:
  /*/**/  “0*/”     /*1“/**/
得到的结果是: “0*/”


聪明的人脚步怎么能停下来?Doug McIlroy发现了下面这个让人拍案叫绝的解法:
    /*/*/0*/**/1

代码如下:
#include<stdio.h>
int main(void)
{
    int a = /*/*/0*/**/1;
    printf("%d\n",a);

    return 0;
}
如果编译器支持嵌套注释,a = 1 反则 a = 0


啊哈,祝大家新年快乐!

评分

参与人数 1荣誉 +3 鱼币 +10 收起 理由
~风介~ + 3 + 10 支持楼主!

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-1-2 19:56:49 | 显示全部楼层
没时间看啊,这书之前也有空看的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-26 16:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表