C陷阱与缺陷 笔记(一): 注释的嵌套

本文介绍了一种用于测试C编译器是否支持嵌套注释的方法,并提供了一个巧妙的示例程序,该程序在不同类型的编译器下会产生不同的执行结果。

某些C编译器允许嵌套注释。请写一个测试程序,要求:无论是对允许嵌套注释的编译器,还是不允许嵌套注释的编译器,该程序都能正常通过编译(无错误消息出现),但是这两种情况下程序执行的结果却不相同。

(提示:再用引号括起来的字符串中,注释符/*属于斯符串的一部分,而在注释中出现的双引号""有属于注释的一部分。)

为了判断编译器是否允许嵌套注释,必须找到这样一组符号序列,无论是对于允许嵌套注释的编译器,还是不允许嵌套注释的编译器,他都是合法的;但是,对于两类不同的编译器,它却意味着不同的事物。这样一组符号序列不可避免地要涉及嵌套注释,让我们从这里开始讨论:

/*/**/


对于一个允许嵌套注释的C编译器,无论上面的符号序列后面跟什么,都属于注释的一部分;而对于不允许嵌套注释的C编译器,后面跟的就是实实在在的代码内容。也许有人因此想到可以在后面再跟一个用一对引号引起的注释结束符:

/*/**/"*/"

如果允许嵌套注释,上面的符号序列就等效于一个引号;如果不允许,那么就等效于一个字符串"*/"。因此,我们可以接着在后面跟一个注释开始符以及一个引号:

/*/**/"*/"/*"

如果允许嵌套注释,上面就等效于用一对引号引起的注释开始符"/*";如果不允许,那么就等效于一个用引号括起的注释结束符,后跟一段未结束的注释。我们可以简单的让最后的注释结束:

/*/**/"*/"/*"/**/

这样,如果允许嵌套注释,上面的表达式就等效于"*/";如果不允许,那么就等效于"*/"。 在我用基本上类似于上面的形式解决这个问题之后,Doug McIlroy发现了下面这个让人拍案叫绝的解法:

/*/*/0*/**/1

这个解法主要利用了编译器作词法分析时的"大嘴法"规则。如果编译器允许嵌套注释,则上式将被解释为:

/* /* /0 */ * */ 1

两个/*符号与两个*/符号正好匹配,所以上市的值就是1。如果不允许嵌套注释,竖直中的/*将被忽略。因此,即使是/出现在注释中也没有特殊的含义;上面的表达式因此将被这样解释:

/* / */ 0* /**/

它的值就是0*1,也就是0

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值