Как вы оформляете основные и второстепенные комментарии? - PullRequest
7 голосов
/ 01 января 2009

Иногда я хочу написать «основной» комментарий для описания большого блока кода, а затем написать «второстепенные» комментарии для описания нескольких строк в этом блоке кода:

// Major comment

// Minor comment
...

// Minor comment 2
...

Основной комментарий выглядит странно без кода под ним, и вы не можете визуально сказать, сколько кода он описывает ниже.

Как вы оформляете эти комментарии?

(я помню, как читал об этом в Code Complete некоторое время назад, но мне не принадлежит книга.)

Ответы [ 12 ]

4 голосов
/ 01 января 2009

Я использую многострочные комментарии для «основных» комментариев:

/*
 * yada yada yada
 */

И используйте однострочные комментарии для второстепенных.

Я знаю, что некоторые люди не любят использовать комментарии в стиле / * * /, потому что это затрудняет автоматическое комментирование и раскомментирование блоков ... но мне нравится, как они выглядят, и я убежден, что код должен быть эстетически приятно читать.

Это также означает, что вы должны иметь возможность анализировать структуру кода в основном без чтения подробностей, что означает, что я склонен использовать довольно много пробелов, а также разделительные строки комментариев, чтобы помочь разобраться. Так что для блока я хочу комментировать, я мог бы написать:

/**
 * detailed description ...
 */

code

// -- minor comment
code

code
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---
2 голосов
/ 01 января 2009
// Major comment
// -------------
...

// Minor comment
...

... // Minor comment (end of line)
1 голос
/ 01 января 2009

Я обычно комментирую блоки кода, используя /* */ в верхней части каждого раздела. Я не использую встроенные комментарии, за исключением особых обстоятельств (например, хитрый код), потому что я чувствую, что комментарии «скрыты», и код может быть расширен позже, и комментарии должны будут управляться на микроуровне. Например:

int parseEverything()
{
    /* Initialize the parser. */
    random_code_here();

    still_more_init();
        /// (Note: the above line still falls under the init section, even if it's separated by a newline.)

    /* Main parser loop. */
    while(!done_parsing) {
        /* Grab the token. */
        if(x) {
            /* Preprocessor stuff. */
            y();
        } else {
            /* Normal token. */
            z();
        }

        /* Insert into tree. */
        make_tree_node();
        insert_into_tree();

        /* Move to next token. */
        ++streamPtr;
            /// (Note: the above could be expanded to take up multiple lines, thus
            ///        if an inline comment were used it'd have to be moved, if
            ///        you even remember there's a comment there.)
    }

    clean_up();
}

Конечно, если код очевиден, он не должен требовать комментария, как в clean_up(). Включение комментария не повредит, хотя, и если его развернуть позже, будет легче узнать, куда добавить дополнительный код очистки.

Используя эту схему, я обнаружил, что легко следовать функции исключительно по ее комментариям. parseEverything имеет три основных раздела: инициализация, основной цикл и очистка. В основном цикле мы берем токен (препроцессор или обычный), вставляем его в дерево и переходим к следующему токену.

Скорее всего, каждый раздел вызывает свой собственный [набор] функций, поэтому ясно, что вам может потребоваться рефакторинг, если разделы становятся громоздкими.

Я должен добавить, что я форматирую многострочные комментарии как таковые (моя «IDE» (Vim) вставляет * в каждую строку для меня со сценариями по умолчанию (для моего дистрибутива), что удобно):

/*
 * This is a comment which normally would be on one line, but is either split into multiple
 * lines for emphasis or so we don't have 160-character hard-to-read comments everywhere.
 */

Также я комментирую #else и #endif:

#ifndef FOO_H
#define FOO_H

#ifdef DEBUG
#else   /* DEBUG */
#endif  /* !DEBUG */

#endif  /* FOO_H */

Но это немного не по теме.

(#include охранникам не требуется not (!) перед ними, потому что их использование очевидно, и это традиция. =])

1 голос
/ 01 января 2009

Здесь все довольно C-ориентировано. В C / C ++ я склонен писать

/* file -- what it is -*-emacs magic-*- */

как первая строка.

/*
 * Block comments like this
 */

if( I need a comment on a code block) {
   /* I tend to write them like this */
   x = x + 1 ;                        /* ... and write my */
                                      /* line comments so */
}

Я обычно резервирую // comments для внутреннего кода и сохраняю старые добрые комментарии BSD для комментариев блока.

В Лиспе

;;;; Four semicolons for "file-scope" comments

;;; Three for block comments over a large chunk of code

(defun quux (foo bar)
    "Don't forget your docstrings, folks"
    ;; but big code comments get two semicolons
    (let ((a 1)
          (b 2))                      ; and only one semicolon
          (+ a b)))                   ; means an in-line comment.

# comment languages like Python and Ruby
# Have to live with one style of comment.
def quux(a,b):
    return a + b                          # poor neglected things.
1 голос
/ 01 января 2009

Я думаю, что разница между «основными» и «второстепенными» комментариями лежит в структурах программы, к которым они прикреплены. Например, я рассматриваю комментарии к документации на уровне методов или классов как «основные», а комментарии на уровне блоков или строк как «второстепенные»:

/**
 * This is major comment describing the method
 */
public void foo() {
    if (...) {
        // minor comment describing block
        ...
        doSomething(); // minor comment describing line
    }
}

Вместо того, чтобы разбивать ваш код комментариями, я думаю, что хорошей практикой является реорганизация функциональных блоков в их собственные методы с описательными именами и комментариями к документам.

1 голос
/ 01 января 2009

Я помещаю основные комментарии над кодом (блоком), которому предшествует пустая строка, а иногда и весь верхний регистр. Незначительные комментарии я отложил справа, с отступом в столбце 81, чтобы убрать их с пути кода. Оба из них, используя //.

Для алгоритмических «дискурсов» я использую / * * / примерно так:

/*
 * This is a long discourse on the code which follows it, usually
 * placed at the beginning of a method and containing information
 * which is not appropriate for the doc comments.
 */
1 голос
/ 01 января 2009

Я использую что-то вроде этого, чтобы это выглядело как «заголовок» или разделитель для следующего блока кода:

// ***** Major comment *****

// Minor comment
...

// Minor comment 2
...

Конечно, это предполагает, что "главный комментарий" - это всего лишь несколько слов

0 голосов
/ 01 января 2009

Это мой стиль комментариев:

/**
 * This is a comment explaining
 * what this method is actually doing
 */
public void foo()
{
    // this is a simple comment
    doSomething();

    // this is a special comment
    // explaining thoroughly what I'm doing
    // using as many words as possible
    // to be the most concise
    doSomethingSpecial();
}
0 голосов
/ 01 января 2009
// Top-level (major) comment
theThing=doSomething();
    // - Second-level (minor) comment
    anotherThing=doSomethingWith(theThing);
        // - - Third-level (minor-minor?) comment
        yetAnotherThing=doSomethingWith(anotherThing);
    // - Back to second level
    destroy(anotherThing);
// Back to first level
helloWorld();

Конечно, трюк с идентификацией не применяется, когда синтаксис не позволяет этого (читай: Python)

0 голосов
/ 01 января 2009

Основной комментарий

/***  Function - fooBar()  ****************************
** Description                                       **
**    does the flooble using the bardingle algorithm **
**      with the flinagle modification               **
** Pre-condition                                     **
**    all moths are unballed                         **
** Post-condition                                    **
**    all moths are balled                           **
******************************************************/
void fooBar( int foo ) {
    ...
    ...
}

/***  Function - fooBar() END  ***********************/

Незначительный комментарий

// note cast to int to ensure integer maths result
int i = (int)y / (int)x;
...