Комментарий — это текст в исходном коде, который компилятор не исполняет: в C на ранней фазе трансляции каждый комментарий заменяется одним пробелом, в C# лексер пропускает его как незначащий фрагмент. Комментарии пишут для людей, которые будут читать код.
Содержание
C и C# — разные языки, но C# унаследовал синтаксис комментариев от семейства C, поэтому // и /* */ в них выглядят одинаково. Различия начинаются в документирующих комментариях: в C# есть встроенный формат XML-документации ///, в C стандартного формата нет, и обычно используют Doxygen.
Разберем синтаксис на запускаемом примере, типичные ошибки с фактическим выводом компилятора и правила, по которым комментарий помогает, а не мешает.
Три вида комментариев: мини-словарь
| Термин | Для кого | Пример | Что с ним делает инструмент |
|---|---|---|---|
| Обычный комментарий | для читателя кода | // повтор при таймауте |
компилятор отбрасывает |
| Документирующий комментарий | для пользователя функции или API | /// <summary>...</summary> |
IDE показывает в подсказках, генератор собирает документацию |
| Закомментированный код | временно отключенный фрагмент | // printf("debug"); |
компилятор отбрасывает, но это не пояснение, а мусор в истории |
Синтаксис комментариев в C
В C два вида комментариев:
- блочный
/* ... */— начинается с/*, заканчивается первым встреченным*/, может занимать несколько строк; есть в языке с первого стандарта C89; - однострочный
// ...— действует до конца строки; в стандарт C вошел в C99 (многие компиляторы понимали его и раньше как расширение).
Минимальный полный пример, который компилируется и запускается:
#include <stdio.h>
/* Площадь прямоугольника.
Размеры в сантиметрах, результат в квадратных сантиметрах. */
static int area(int width, int height)
{
return width * height; // переполнение int не проверяем: учебный пример
}
int main(void)
{
int w = 12, h = 5;
// Выводим результат одной строкой
printf("area = %d\n", area(w, h));
printf("// это не комментарий, а часть строки\n");
return 0;
}
Программа печатает две строки:
area = 60
// это не комментарий, а часть строки
Что здесь видно:
- блочный комментарий над функцией описывает контракт: единицы измерения, которых нет в коде;
- комментарий справа от
returnназывает границу примера, а не пересказывает умножение; //внутри строкового литерала — это просто символы строки. Комментарием он становится только вне литералов.
Синтаксис комментариев в C
В C# те же // и /* */ плюс документирующий комментарий /// (реже встречается блочная форма /** ... */).
using System;
public static class Geometry
{
/// <summary>
/// Считает площадь прямоугольника.
/// </summary>
/// <param name="width">Ширина в сантиметрах, не меньше нуля.</param>
/// <param name="height">Высота в сантиметрах, не меньше нуля.</param>
/// <returns>Площадь в квадратных сантиметрах.</returns>
/// <exception cref="ArgumentOutOfRangeException">Если размер отрицательный.</exception>
public static int Area(int width, int height)
{
ArgumentOutOfRangeException.ThrowIfNegative(width);
ArgumentOutOfRangeException.ThrowIfNegative(height);
return width * height; // checked-контекст не включаем: учебный пример
}
public static void Main()
{
/* Блочный комментарий работает так же, как в C */
Console.WriteLine($"area = {Area(12, 5)}"); // выведет: area = 60
}
}
При запуске в консоли появится area = 60. Главное здесь — комментарий ///: в Visual Studio, Rider и VS Code с расширением C# текст из <summary> и <param> всплывает в подсказке, когда вы вызываете Geometry.Area.
Основные XML-теги документации:
| Тег | Что описывает |
|---|---|
<summary> |
краткое назначение типа или метода |
<param name="..."> |
один параметр |
<returns> |
возвращаемое значение |
<exception cref="..."> |
исключение и условие, при котором оно бросается |
<remarks> |
подробности, которые не влезли в summary |
<example>, <code> |
пример использования |
<inheritdoc/> |
взять документацию у базового члена или интерфейса |
Чтобы компилятор собрал XML-файл документации рядом со сборкой, в .csproj включают свойство:
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>
После этого компилятор начинает предупреждать о публичных членах без документации (предупреждение CS1591).
Документирующие комментарии в C: Doxygen
У C нет встроенного формата документации, де-факто стандарт — Doxygen. Он читает комментарии вида /** ... */ или /// с командами @brief, @param, @return:
/**
* @brief Считает площадь прямоугольника.
* @param width ширина в сантиметрах
* @param height высота в сантиметрах
* @return площадь в квадратных сантиметрах
*/
int area(int width, int height);
Для компилятора это обычный блочный комментарий: без запуска Doxygen он ничего не меняет в программе. Комментарий к функции обычно ставят в заголовочный файл .h, потому что именно его читает пользователь функции.
Типичные ошибки с комментариями в C
Ошибка 1: вложенный блочный комментарий
Блочные комментарии в C (и в C#) не вкладываются: комментарий заканчивается на первом */. Если закомментировать блоком фрагмент, где уже есть /* */, хвост окажется снаружи.
/* старый блок /* пояснение */ x = 0; */
Фактический результат (Apple clang 21; текст и порядок сообщений в GCC и MSVC другие):
warning: '/*' within block comment [-Wcomment]
error: use of undeclared identifier 'x'
error: expected expression
Исправление — отключать большие куски кода условной компиляцией, а не комментарием. Директивы #if 0 … #endif вкладываются и не конфликтуют с /* */ внутри:
#include <stdio.h>
int main(void)
{
#if 0
/* старая версия расчета */
printf("old\n");
#endif
printf("new\n");
return 0;
}
Выведется только new. В долгосрочной перспективе отключенный код лучше удалить: старая версия останется в истории Git.
Ошибка 2: обратный слеш в конце однострочного комментария
Обратный слеш в самом конце строки склеивает ее со следующей еще до того, как компилятор ищет комментарии. Если //-комментарий заканчивается на \, следующая строка тоже становится комментарием.
#include <stdio.h>
int main(void)
{
int limit = 10;
// временный каталог: C:\temp\
limit = 99;
printf("limit = %d\n", limit);
return 0;
}
Фактический результат: программа печатает limit = 10, присваивание limit = 99 молча пропало. Clang с -Wall предупреждает multi-line // comment [-Wcomment], без флагов предупреждений ошибка может пройти незаметно. Исправление — не заканчивать комментарий обратным слешем: написать C:\temp без завершающего слеша или взять путь в кавычки.
Ошибка 3: комментарий, который врет
Компилятор не сверяет комментарий с кодом. Если логику поменяли, а комментарий нет, он начинает вводить в заблуждение:
/* Возвращает площадь в квадратных метрах */
int area(int width, int height); /* на деле - сантиметры */
Исправление — править комментарий в том же коммите, что и код, а единицы и ограничения по возможности выражать в именах: area_cm2(int width_cm, int height_cm).
Как писать полезные комментарии
Строгих правил нет, это соглашения команды, но руководства по стилю сходятся: комментарий объясняет то, чего нельзя понять из кода.
| Ситуация | Вместо комментария | Когда комментарий нужен |
|---|---|---|
| непонятно, что хранит переменная | переименовать: t -> timeout_ms |
единица или диапазон не выражаются в имени |
| длинный кусок логики | вынести в функцию с говорящим именем | неочевидная причина решения |
| обход бага библиотеки или ОС | — | всегда: что за баг, где описан, когда можно убрать |
| формула или алгоритм | — | ссылка на источник и условия применимости |
| публичный API | — | документирующий комментарий: параметры, результат, ошибки |
Сравните два комментария к одной строке:
i++; /* увеличиваем i на 1 */
i++; /* пропускаем заголовок CSV: первая строка файла - имена колонок */
Первый повторяет код и ничего не добавляет. Второй объясняет причину, которую из i++ не восстановить.
Короткий чек-лист перед коммитом:
- Комментарий отвечает на вопрос «почему», а не пересказывает «что».
- Он описывает текущее поведение, а не историю правок (история — в сообщениях коммитов).
- Публичные функции документированы: параметры, возвращаемое значение, ошибки.
- В коде не осталось закомментированных блоков без причины.
- Однострочный комментарий не заканчивается обратным слешем.
Выводы
- В C есть
/* */(с C89) и//(с C99); в C# те же два вида плюс XML-документация///. - Блочные комментарии не вкладываются ни в C, ни в C#; для отключения кода в C надежнее
#if 0…#endif, а лучше удаление и история Git. //внутри строкового литерала не комментарий, а обратный слеш в конце//-строки превращает в комментарий и следующую строку.- Документирующие комментарии читают инструменты: в C# — компилятор и IDE (XML-файл, CS1591), в C — Doxygen.
- Полезный комментарий объясняет причину, единицы, ограничения и обходы багов; то, что можно выразить именем, лучше выразить именем.
Где применяется / связь с практикой
Умение документировать код особенно важно в системной разработке на C: там на один заголовочный файл опираются десятки модулей, а контракт функции (кто освобождает память, какие коды ошибок, потокобезопасна ли она) из сигнатуры не виден.
Освойте тему на практике
Если хотите писать на C низкоуровневый код — работу с памятью, процессами, файлами и сетью на уровне ОС, — посмотрите курс по системному программированию. Попробовать формат обучения бесплатно можно на открытых уроках Otus.
FAQ
Влияют ли комментарии на скорость или размер программы?
Нет. Комментарии удаляются на этапе трансляции и в исполняемый файл не попадают. XML-документация C# сохраняется отдельным файлом рядом со сборкой, а не внутри нее.
Можно ли поставить комментарий в середину строки кода?
Да, блочный: int x = /* начальное */ 0; корректно в C и C#. Однострочный // так не получится, он отключает все до конца строки.
Как быстро закомментировать несколько строк в редакторе?
В VS Code — Ctrl+/ (на macOS Cmd+/), в Visual Studio — Ctrl+K, Ctrl+C, а раскомментировать — Ctrl+K, Ctrl+U. Сочетания зависят от раскладки и настроек редактора.



