プログラムの振る舞いだけでなく、意図や背景を伝えるのがコメントです。
特にC言語は記述の自由度が高いため、読み手が理解しやすいコメントを書けるかどうかで保守性が大きく変わります。
本稿では、C言語のコメントの基本から具体的な書き方、注意点、実務で役立つ規約やDoxygenまで、入門者向けに段階的に解説します。
C言語 コメントの基本
コメントの役割と効果
目的は「何を」ではなく「なぜ」を伝える
コメントはコードの説明書です。
コンパイラはコメントを無視するため、実行速度やメモリ使用量には影響しません。
では、何のために書くのでしょうか。
最大の目的は「意図の共有」です。
コードを読めば分かる事実の重複ではなく、なぜその実装を選んだのか、前提条件や制約、注意すべき副作用など「理由」を記述することで、読み手が誤解なく保守できます。
コメントは最終手段であり設計の補助
読みづらいコードをコメントで補うより、まずは命名や分岐の分解、関数化で読みやすくすることが先です。
その上で、設計上の判断や仕様の背景などコードだけでは伝わらない事柄をコメントに残します。
C言語のコメント種類(// と /* */)
2種類の基本構文
C言語では2種類のコメント記法が使えます。
どちらもトークンとしては空白に置き換えられます。
//
行コメント: 行末までがコメントになります。/* ... */
ブロックコメント:*/
が現れるまでがコメントになります。
次の違いを押さえて使い分けます。
種類 | 範囲 | 主な用途 | 注意点 |
---|---|---|---|
// 行コメント | 改行まで | 行末の補足、短い説明 | C99以降で標準。C90では非標準に注意。行末のバックスラッシュ続行に注意。 |
/* ... */ ブロックコメント | */ まで | ファイルや関数のヘッダ、複数行説明 | ネスト不可。*/ の閉じ忘れで大規模に壊れる。 |
文字列リテラル内の //
や /*
はコメントにはなりません。
たとえば printf("http://example.com");
は正しく文字列として扱われます。
C99の行コメントとC90の注意点
どの規格をターゲットにするかで選び方が変わる
//
はC99で標準化されたため、古いC90(C89、ANSI Cとも)では標準外です。
多くのコンパイラは拡張で受け付けますが、移植性重視なら以下の方針が安全です。
- C99以降が前提なら、行末の短い補足に
//
を積極活用する。 - C90互換が必要なら、コメントは
/* ... */
に統一するか、ビルドオプションで規格を明示する。
たとえばGCCでは -std=c99
、-std=c11
などで規格を指定します。
制定年 | 規格名 | GCCでの指定例 |
---|---|---|
1990 | C90(C89) | -std=c90 / -std=c89 |
1994 | C95 | -std=iso9899:199409 |
1999 | C99 | -std=c99 |
2011 | C11 | -std=c11 |
2017/2018 | C17(C18) | -std=c17 / -std=c18 |
2023/2024 | C23 | -std=c23 |
現在推奨されている規格は、最新のC23(-std=c23
または GNU拡張込みの -std=gnu23
)です。
C90互換をチェックするなら -std=c90 -pedantic
を使うと拡張使用を警告できます。
MSVCなど一部コンパイラはC90モードでも //
を受け付ける拡張があるため、チームの標準を決めておくことが大切です。
書く場所の基本(ファイル・関数・変数)
ファイル先頭のヘッダコメント
ファイルが何を提供するのか、依存関係、ライセンス、連絡先などを要約します。
ヘッダファイルでは公開APIの範囲も記しましょう。
関数の直前
関数の目的、前提条件、引数の意味、戻り値、スレッド安全性、失敗時の挙動などを要点として記します。
ドキュメント生成を視野に入れるならDoxygenスタイルにすると後述の自動化に繋がります。
変数・フィールドの横(あるいは直上)
単位(例: ms、bytes)、境界値、所有権(誰が解放するか)、不変条件など、誤用を防ぐ情報を添えます。
横に書く場合は位置を揃えて可読性を高めます。
場所 | 目的 | 書く内容の例 |
---|---|---|
ファイル先頭 | 全体の要約 | 役割、依存、ライセンス、注意事項 |
関数直前 | API仕様 | 目的、前提、引数、戻り値、副作用、例外 |
変数・構造体 | 誤用防止 | 単位、範囲、所有権、不変条件 |
C言語 コメントの書き方と例
行コメント(//)の書き方
短い補足や例外の注記に適する
//
は当該行の末尾までがコメントになります。
短く、対象のコードに近接して書けるため、局所的な補足に向いています。
行末にバックスラッシュ \
があると物理的な次行と結合され、コメントが次行に伸びてしまうことがあるため注意します。
#include <stdio.h>
int main(void) {
int width = 12; // 幅(ピクセル)
int height = 8; // 高さ(ピクセル)
int area = width * height; // 長方形の面積
printf("area=%d\n", area); // 出力: area=96
// printf は改行を自動では付けない点に注意
// 行末のバックスラッシュで次行と結合される例(非推奨):
// int x = 1; // ここで\
printf("この行もコメント扱いになります\n");
return 0;
}
area=96
よくある落とし穴
- URLなどの文字列中の
//
はコメントではありません。printf("http://example.com\n");
は安全です。 - 行頭のインデント位置に合わせずにばらばらに書くと読みにくくなります。エディタの「コメント桁位置」を活用すると整い、差分も見やすくなります。
ブロックコメント(/* */)の書き方
複数行の説明やヘッダに向いている
/* ... */
は */
までがコメントです。
関数やファイルのヘッダ、アルゴリズムの概説など、まとまった説明に適します。
/*
* image.c - 2D画像処理ルーチン
* 役割:
* - グレースケール変換
* - 二値化(閾値指定)
* 注意:
* - 入力バッファと出力バッファの重なりは未対応
* - ピクセルは8bit固定
*/
#include <stddef.h>
/* バッファを閾値で二値化する。inとoutは別領域を想定。 */
void binarize_u8(const unsigned char *in, unsigned char *out, size_t n, unsigned char th);
一時的なコメントアウトにも使えるが慎重に
コードの塊を無効化する目的で /* ... */
を使うと便利ですが、コメントのネストができないため、内部にすでにブロックコメントがあると崩壊します。
後述の #if 0
の方が安全です。
複数行コメントの整形ルール
読みやすく、検索しやすく
複数行のブロックコメントは、先頭の /*
と末尾の */
を目立たせ、各行頭に整列した *
を置くと読みやすくなります。
説明の1行目は要点、以降は詳細という順にしましょう。
/*
* DCTの高速化について
* - 係数の事前計算で乗算回数を削減する。
* - 浮動小数の誤差に注意し、整数量子化は最後に行う。
* 参照: JPEG ISO/IEC 10918-1
*/
Doxygenを使う場合は /** ... */
や ///
を用いると自動ドキュメント化できます(詳細は後述)。
例: 変数・関数へのコメント
小さなプログラムで全体の流れと意図を伝える
短いプログラムに、ファイルヘッダ、関数ヘッダ、変数の補足を加えた例です。
#include <stdio.h>
/*
* 温度変換ユーティリティ
* 目的:
* 華氏を摂氏に変換する簡単なサンプル。
* 注意:
* 四捨五入は行わず、小数は表示用に丸めるだけ。
*/
/* 華氏から摂氏へ変換する。
* 引数:
* f(華氏)
* 戻り値:
* 摂氏
*/
static double fahrenheit_to_celsius(double f) {
return (f - 32.0) * 5.0 / 9.0; // 式の由来: 国際標準の線形変換
}
int main(void) {
double f = 77.0; // 入力温度(華氏)
double c = fahrenheit_to_celsius(f); // 変換結果(摂氏)
printf("F=%.1f -> C=%.2f\n", f, c); // 表示は小数2桁に丸め
return 0;
}
F=77.0 -> C=25.00
このように、変換式の由来や丸め方の方針など「なぜ」を短く添えると、読み手が安心して変更できます。
コメントの注意点とベストプラクティス
ネスト禁止と閉じ忘れ(/* */)
ブロックコメントは入れ子にできない
/* ... */
は最初に現れた */
で閉じます。
入れ子にすると意図しない箇所で閉じられ、以降のコードがコメントの一部になったり、逆に未閉鎖でファイル末尾までコメント扱いになったりします。
int main(void) {
/* 外側のコメント開始
内部で /* さらにコメント */ と書くと
↑ここで先に閉じてしまうため、以下がコードとして解釈され壊れる */
return 0;
}
この例では「さらにコメント」の後ろの */
で外側まで閉じてしまい、残りが崩れます。
ネストの必要がある場合は、外側を #if 0 ... #endif
にし、内側は通常の /* ... */
にするのが安全です。
コメントアウト多用を避ける
バージョン管理と条件コンパイルを活用する
過去の実装を残す目的で巨大なブロックをコメントアウトすると、読みづらくメンテナンスの妨げになります。
履歴はGitなどのバージョン管理に任せ、ビルド時に切り替えたい場合はプリプロセッサを使います。
#include <stdio.h>
int main(void) {
#if 0
// 古い実装(保持したいならGitの過去コミットで管理)
printf("old path\n");
#else
// 現行実装
printf("new path\n");
#endif
return 0;
}
new path
#if 0
はネストされたブロックコメントがあっても安全に無効化できるのが利点です。
誤解や陳腐化を防ぐ書き方
事実の重複より意図と前提を書く
コードから自明なこと(例: i = 0; // iを0にする
)は不要です。
代わりに境界条件や理由、単位、影響範囲を記します。
また、コメントはコード変更に追従させましょう。
古いコメントはバグの温床です。
int timeout = 1000; // タイムアウト
int timeout_ms = 1000; // タイムアウト(ミリ秒)。API仕様上の上限は2000ms。
コメントは空白に置き換えられることを意識する
プリプロセッサはコメントを実質的に空白として扱います。
トークンを結合する目的でコメントを挟むテクニックは不正確で移植性がありません(トークン結合は ##
を使用)。
日本語/英語の使い分けと文字コード
チームとツールが読める言語とエンコーディングを選ぶ
実装者もレビュアも日本語話者であれば、日本語で明確に意図を書けます。
一方、OSS公開や多国籍チームでは英語が適します。
混在する場合は公開範囲と読者を意識して決めましょう。
文字コードはUTF-8が一般的で、BOMなしが無難です。
Windows環境ではエディタとビルドツールの設定を合わせ、文字化けを防ぎます。
場面 | 推奨言語 | 補足 |
---|---|---|
社内日本人チーム | 日本語 | 誤読防止を最優先。専門用語は原語も併記すると良い。 |
OSS/国際チーム | 英語 | Doxygenコメントも英語に統一。 |
外部公開なしの検証コード | 任意 | 将来の再利用を考えUTF-8で統一。 |
実務で使えるコメント術
コメント規約の例(TODO, FIXME, NOTE)
検索しやすいラベルを決めてチームで統一
作業の残件や注意点を埋もれさせないため、目印のラベルを導入します。
大文字の短いタグを先頭に置くと、検索やCIでの抽出が容易です。
// TODO(taro, 2025-08-01): 入力検証を厳密化する(rangeチェックを追加)。
// FIXME: WindowsでEOF処理が不正。バイナリモード指定を調査。
// NOTE: この関数は低頻度呼び出しのためO(n^2)でも許容。
エディタやCIで TODO|FIXME|NOTE
を集計し、未対応の残件を見える化すると運用が安定します。
Doxygen記法でAPIドキュメント化
コメントからドキュメントを自動生成する
DoxygenはCのコメントからHTMLやPDFのAPIリファレンスを生成します。
エクスポートしたい関数や構造体に /** ... */
の形式で書き、@param
や @return
で仕様を明確に記します。
#include <stddef.h>
/**
* @brief メモリブロックを指定値で埋める(安全版)。
*
* バッファ長をチェックし、NULLは無視します。
*
* @param buf 対象バッファ(書き込み先)
* @param value 設定する値(0..255)
* @param len バッファ長(バイト)
* @return 実際に書き込んだバイト数
*/
size_t fill_u8(unsigned char *buf, unsigned char value, size_t len) {
if (buf == NULL) {
return 0; // NOTE: NULLは無視し、0を書き込んだとみなす
}
for (size_t i = 0; i < len; ++i) {
buf[i] = value;
}
return len;
}
Doxygenの実行例:
- 設定ファイルを作成:
doxygen -g
EXTRACT_ALL = YES
、OPTIMIZE_OUTPUT_FOR_C = YES
などを設定doxygen Doxyfile
を実行するとhtml/
に出力されます
ドキュメントが仕様の単一情報源となるため、実装とコメントを同時に更新する文化を根付かせやすくなります。
コードレビューでのコメントチェック
コメント品質の観点をレビューに組み込む
レビューではロジックだけでなく、コメントの妥当性も確認します。
観点を明文化しておくと合意が取りやすく、品質が安定します。
観点 | 確認内容 |
---|---|
正確性 | 現行コードと矛盾していないか。単位や境界値が正しいか。 |
必要性 | 自明な説明になっていないか。「なぜ」を説明しているか。 |
位置 | 読み手が欲しい場所にあるか。ファイル/関数/変数に適切に分配されているか。 |
可読性 | 文の簡潔さ、用語の統一、長文の段落化、折り返し幅が適切か。 |
維持容易性 | DoxygenタグやTODOが運用に乗っているか。規約に沿っているか。 |
まとめ
コメントはコードの一部であり、読み手への最短の道案内です。
C言語では //
と /* ... */
を用途に応じて使い分け、C90とC99の違いを意識しながら、ファイル・関数・変数に適切な情報を配置します。
複数行は整形を整え、ネスト禁止や閉じ忘れなどの罠を避けます。
不要なコメントアウトは控え、履歴はバージョン管理に任せましょう。
内容は「なぜ」を中心に、単位や前提・副作用を明記し、言語と文字コードはチームの現実に合わせて統一します。
実務ではTODOやFIXMEの規約とDoxygenを取り入れることで、コメントがドキュメントとして生き、レビューで品質を継続的に高められます。
コメントの力を味方に、読みやすく壊れにくいCコードを書いていきましょう。