【问题标题】:why can't we nest one comment inside another comment?为什么我们不能将一条评论嵌套在另一条评论中?
【发布时间】:2023-03-05 09:24:01
【问题描述】:
/*
/**hiiii**/
*/

假设我像这样嵌套 cmets,那么这有什么问题?一开始我们有/*,然后里面有一些字符串,最后我们有*/,那么这里的错误是什么?

【问题讨论】:

  • cmets 在看到匹配的 */ 结尾时停止,如果您想要嵌套注释,只需使用内部的 //。
  • 要暂时禁用一段包含 cmets 的代码,使用#if 0。某些 IDE 提供的替代方法是通过在每行开头插入 // 将一段代码转换为 cmets 的快捷键。
  • a = 42; // outer comment // inner, nested comment :)
  • 因为语言就是这样设计的。

标签: c syntax comments


【解决方案1】:

C 标准对此非常明确。 /*...*/ 样式 cmets 不嵌套,因为语言语法不允许 嵌套

引用C11,第 6.4.9 章,评论,(强调我的

除了字符常量、字符串文字、或注释、字符/* 介绍评论。仅检查此类评论的内容以识别 多字节字符并找到终止它的字符*/83)

以及相关的脚注,

83) 因此,/* ... */ cmets 不会嵌套。

详细说明,如您的情况,

/*                  <-- Comments starts here
/**hiiii**/         <-- Found the ending */, so comment ends.
*/                  <-- problem here....
  • 在第一行,/* 开始评论。
  • 如前所述,在以/* 开头的第二行开始评论。
  • 在第二行结尾,*/ 终止注释。因此,在第三行中,*/ 会产生错误。

【讨论】:

  • 这并没有回答为什么不能在 C 中使用嵌套 cmets 的问题。
  • @VladfromMoscow 对不起,先生,没有得到你。我错过了什么?
  • @VladfromMoscow “因为”这就是语言的定义方式。这种行为比 C11 早了一点;我似乎记得它在 C86 中是这样工作的,当我学习它时,这是相当新的。
  • @SouravGhosh 为什么 C 不允许嵌套 cmets?
  • @VladfromMoscow 嗯,这取决于 cmets 的风格。 //some //comment 是有效的嵌套 cmets。不是吗? /*..*/ 风格,OTOH,不嵌套。
【解决方案2】:

为什么我们不能将一条评论嵌套在另一条评论中?

因为语言设计者同情语言实现者。

解析不可嵌套的 cmets 非常容易;解析可嵌套的 cmets 不太容易。

// pseudo code for unnestable comments
is the character a '*'? YES => Is the next one a '/'? YES END COMMENTS
else STILL INSIDE A COMMENT

【讨论】:

  • 嵌套 cmets 的伪代码:inside_comment = 0; if ( "/*" ) inside_comment++; if ( "*/" ) inside_comment--; 因此,零值表示您在任何评论之外,正值表示您在评论内,负值表示错误。跨度>
  • @user3386109:我没有说这很困难 :)
【解决方案3】:

代码可以有效地使用#if 0 嵌套注释行为。因此不需要扩展/* */ 行为。

#if 0

   blah blah 

#if 0
   blah blah 

#endif

   blah blah 

#endif

【讨论】:

    【解决方案4】:

    /**hiiii**/ 行末尾的 */ 是注释的结束。

    这样做:

    /*
    //*Hiiii*
    */
    

    【讨论】:

      【解决方案5】:

      在看到/* 之后,编译器会寻找*/。一旦找到更接近*/ 的评论,就完成了。从/* 到第一个*/ 的所有内容都被视为评论。所以,

      /*
      /**hiiii**/ 
      

      发表评论。

      第二个*/ 没有前面的/*,因此会导致错误。

      【讨论】:

        【解决方案6】:

        /* 引入的 C cmets 不嵌套。这个决定是由最初的设计者在 40 多年前做出的,所有的 C 标准都规定了这一点。尽管一些较旧的编译器支持使用命令行开关嵌套此类 cmets,但强烈建议遵守标准做法并考虑 cmets 在字符 */ 的第一次出现处结束。

        请注意,/* 可以用转义换行符分隔(\ 后跟换行符:

        int i = 3;  /\
        * This is a comment (SO syntax coloring is not perfect ;-) *\
        / printf("%d\n", i); // prints 3
        

        另外请注意,通过/**/ 将代码变成注释来注释代码是一个坏主意。如果您的代码包含 C cmets,这将失败,甚至可能静默失败:

        int i = 3, j = 6;
        /* printf("debug: i=%d\n", i);  /* check the value of i */
        printf("debug: j=%d\n", j);  // check the value of j */
        

        在上面的代码中,第二个printf 没有被注释

        你可以想象更棘手的情况:

        /*
        // list all C source files in subdirectories
        system("ls */*.[ch]");
        */
        

        注释一段代码有两种有效的方法:

        • 使用 #if 0 / #endif 预处理器指令。通过将#if 0 更改为#if 1,这些可以嵌套并轻松取消注释

        • 在块中每一行的开头插入//。这可以嵌套,意思是您可以通过在每行的开头再次插入//注释一个更大的块。

        【讨论】:

          猜你喜欢
          • 2013-05-19
          • 2021-09-09
          • 1970-01-01
          • 2012-09-17
          • 2015-09-04
          • 1970-01-01
          • 1970-01-01
          • 2014-01-02
          • 1970-01-01
          相关资源
          最近更新 更多