Doxygen 在C+中使用C风格的注释是一种不好的做法吗+;密码?

Doxygen 在C+中使用C风格的注释是一种不好的做法吗+;密码?,doxygen,c++,coding-style,comments,Doxygen,C++,Coding Style,Comments,在阅读维基百科关于的文章时,我发现了这样一句话: 许多程序员避免使用C风格的注释,而是使用C++。 设置单行注释的样式 这是正确的吗?若然,原因为何?这仅仅是一种习惯,还是背后有一些技术和理性的原因 上述条款的例子: /** * <A short one line description> * * <Longer description> * <May span multiple lines or paragraphs as needed> *

在阅读维基百科关于的文章时,我发现了这样一句话:

许多程序员避免使用C风格的注释,而是使用C++。 设置单行注释的样式

这是正确的吗?若然,原因为何?这仅仅是一种习惯,还是背后有一些技术和理性的原因


上述条款的例子:

/**
 * <A short one line description>
 *
 * <Longer description>
 * <May span multiple lines or paragraphs as needed>
 *
 * @param  Description of method's or function's input parameter
 * @param  ...
 * @return Description of the return value
 */
/**
* 
*
* 
* 
*
*@param方法或函数输入参数的说明
*@param。。。
*@return返回值的描述
*/
vs

//
///
/// 
/// 
///
///@param方法或函数输入参数的说明
///@param。。。
///@return返回值的描述

这完全是一个什么是可接受的风格的问题-在任何一种语言中使用一种风格而不使用另一种风格(除非您有一个非常旧的编译器)都没有技术原因

一些社区会期望一种风格的评论——比如Linux内核(C社区)将期待C风格的评论,但是内核源代码的快速GRUP显示了一些C++风格的注释已经加入。


因此,如果您正在为一个项目做出贡献,那么您应该遵循已经在那里使用的样式。如果您是单独工作或类似工作,您可以使用您喜欢的方式,但最好不要混淆样式。

C样式注释
/**/
不能递归嵌套。将多个单行注释相互堆叠(如“//”这样)不是问题。通过这种方式,您可以增量注释掉部分代码。 例如,VisualStudio支持此功能,并以这种方式增加/减少注释级别的数量

支持“/**/”式注释的一个原因是在滚动代码时突出特殊类型的注释,例如方法文档。这也为代码创建了一个很好的视觉结构

“/**/”注释的另一个用例是两边都有代码的内联注释,例如
void myfunc(double size/*=0*/){…}
,以使默认值在cpp文件中可见

结合这两种好处的一种可能方法是:

  • 在方法内部使用“//”(您希望在其中重复输入/输出注释),并
  • 仅对特殊类型的注释使用“/**/”,例如cpp中的doxygen文档

因为C和C++都支持这两种注释,所以既没有C风格注释也没有C++风格注释。 因此,在一行末尾最好使用//comments,而在使用//*..*/注释时,一长段注释更具可读性


至于我,我通常更喜欢使用/*..*/关于我放在函数定义或声明之前的函数的一般描述的注释。如果我需要在某段代码中的某个语句中添加注释,并且只插入一行注释就足够了,我会使用//coments。

我认为这确实是一个品味问题

有许多惯例,只要有一个以上的选择,就会有讨论。匈牙利与非匈牙利符号、蛇格与骆驼格等也同样适用

一般来说,这取决于几个因素:

1) 什么是可以接受的风格。 若你们在大型项目中工作,你们通常必须(而且应该)遵守编码风格的一般规则。在同一项目的不同文件中使用不同的注释样式是非常不可取的

2) 团队中大多数人喜欢的。 应讨论可接受的约定,以适合开发人员的偏好。应该没有压力——只要大家都同意一切都好

3) 技术要求是什么。 如果您需要某种形式的嵌套,您应该仔细考虑。不能嵌套多行注释。按以下顺序:

/* -> 1 start /* -> 2 start */ -> 2 end */ -> 1 end 让我们评论一下整个函数[按Ctrl-K-C…]。结果是:

//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p;
//    ++k;
//  }
//}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline is required.
    ++p;
    ++k;
  }*/
}
让我们一边注释正文,一边将其置为空[按Ctrl-K-C…]。结果是:

//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p;
//    ++k;
//  }
//}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline is required.
    ++p;
    ++k;
  }*/
}
当您预测代码的某些部分可能会暂时从源代码中排除时,使用单行注释是非常重要的。让我们思考一下,如果我们的while的主体包含一条评论,会发生什么:

1) 第一种情况,SL评论:

//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p; //some comment -> ok, '//' can be nested
//    ++k;
//  }
//}
//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p; /*some comment*/ -> ok, '/**/' can be nested inside //
//    ++k;
//  }
//}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline  is required.
    ++p; //some comment -> ok, '//' can be nested inside multiline 
    ++k;
  }*/
}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline  is required.
    ++p; /*some comment*/
    ++k;
  }*/ -> oh..
}
2) 第一个案例,ML评论:

//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p; //some comment -> ok, '//' can be nested
//    ++k;
//  }
//}
//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p; /*some comment*/ -> ok, '/**/' can be nested inside //
//    ++k;
//  }
//}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline  is required.
    ++p; //some comment -> ok, '//' can be nested inside multiline 
    ++k;
  }*/
}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline  is required.
    ++p; /*some comment*/
    ++k;
  }*/ -> oh..
}
3) 第二种情况,SL评论:

//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p; //some comment -> ok, '//' can be nested
//    ++k;
//  }
//}
//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p; /*some comment*/ -> ok, '/**/' can be nested inside //
//    ++k;
//  }
//}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline  is required.
    ++p; //some comment -> ok, '//' can be nested inside multiline 
    ++k;
  }*/
}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline  is required.
    ++p; /*some comment*/
    ++k;
  }*/ -> oh..
}
4) 第二个案例,ML评论:

//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p; //some comment -> ok, '//' can be nested
//    ++k;
//  }
//}
//void f()
//{
//  int p = 0;
//  int k = 0;
//  while(true) {
//    ++p; /*some comment*/ -> ok, '/**/' can be nested inside //
//    ++k;
//  }
//}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline  is required.
    ++p; //some comment -> ok, '//' can be nested inside multiline 
    ++k;
  }*/
}
void f()
{
  int p = 0;
  int k = 0;
  while(true); /*{ -> comment was invoked inside the line, multiline  is required.
    ++p; /*some comment*/
    ++k;
  }*/ -> oh..
}

由于SO使用相同的规则解析注释,所以您应该看到上一个示例中的最后一个标记没有变灰。从我的观点来看,这是一件重要的事情,因为我经常使用块(un)注释。

对于多行,我将使用
/**/
,但是对于单行,小注释,我更喜欢
/
@GrijeshChauhan,我也会这样做。但问题是,为什么要对多行注释使用
/
?一个可能的原因是,您可以快速注释掉包含
/
注释但不包含
/***/
注释的代码块。
#如果0#Endif对注释代码很有帮助。我更喜欢C++风格的注释,因为您总是可以告诉——即使在上下文之外——是否已经注释了一行。我以前在grepping时被C风格的注释烧坏了。这是IDE或文本编辑器在自动插入注释时使用单行注释的一个很好的原因。但这并不是一个避免自己使用它们的好理由,除非你的工具太差,以至于你不得不自己评论,在这种情况下,你需要解决更严重的生产力问题:-)