More than code

More Than Code
The efficiency of your iteration of reading, practicing and thinking decides your understanding of the world.
  1. 首页
  2. daily
  3. 正文

Daily C/C++ 嵌套注释

2021年5月4日 570点热度 0人点赞 0条评论

嵌套注释

这个问题来自《C Traps and Pitfalls》

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

提示:在用双引号括起的字符串中,注释符 /* 属于字符的一部分,而在注释中出现的双引号 "" 又属于注释的一部分

首先你可能会想,什么是嵌套注释

从编译器的角度来说,就是当处理注释的过程中,是允许继续读入 /* */ 这样的符号的

比如一个字符串 /*/**/ , 对于可以嵌套注释的编译器来说, 这是一个未完成的注释,也就是说,后面的任何内容都将被解析为注释,因为第一个 /* 没有找到他对应的 */

那么对于不可以嵌套注释的来说,这就是一段完整的注释,其中注释的内容为 /* ,因为解析规则是这样的,编译器看到了一个注释开始符号,然后将后面的所有字符都解析为注释,直到遇到 */ 才结束

更形象点来说,嵌套注释就像是括号匹配,我们有一个计数器 cnt ,遇到 /* 我们就 cnt++, 遇到 */ 我们就 cnt-- ,那么对于任何时刻的字符来说,当且仅当 cnt != 0 时,我们将其看做注释

而不允许嵌套注释的情况下,我们有一个 flag, 最开始是假,当我们遇到 /* 的时候我们将 flag 设为真, 遇到 */ 时我们将 flag 设为假, 那么对于任何时刻的字符来说,当且仅当 flag == true 时,我们将其看做是注释

当理解清楚嵌套注释和非嵌套注释的区别了以后,我们就可以根据他们的性质来针对性的进行构造

考虑这样一个字符串 /*/**/*/

对于允许嵌套的编译器来说,这就是一段注释,而对于不允许嵌套的编译器来说,这一段代表了 */ (虽然看上去每一段注释都闭合了,但是从左向右模拟一遍就可以发现问题)

这时候就需要题中提示的来帮助我们解决问题了,我们需要用注释符和双引号来配合

关键在于我们解析注释的方法变了的同时,注释的区域也发生了改变

我们用双引号包围最后的注释结束符,/*/**/"*/" ,那么对应的非嵌套版本就是 "*/" ,而嵌套版本就是 "

现在我们希望闭合这个双引号,如果我们在字符串后面加上 /*"*/,将不会对非嵌套版本造成影响,但是在闭合引号的同时,我们也在后面加上了 */,那么我们考虑加上 /*"/**/ 即可

最终结果就是 /*/**/"*/"/*"/**/

原书中有这道题的答案,写的也很棒,十分推荐看一下。

标签: c++
最后更新:2021年5月8日

sheep

think again

点赞
下一篇 >

文章评论

取消回复

COPYRIGHT © 2021 heavensheep.xyz. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS