コードを読みやすく、保守性を高めるように書くことはとても重要です。しかしこの「読みやすい」という感覚は人それぞれで、突き詰めれば突き詰めるほど個人ごとに癖のあるコードになっていきます。そこで本ページでは、コードの記述方法(スタイル)を統一するための一例を紹介します。
- スペースの有無や位置揃えについては、ClangFormatなどの整形ツールを頼ってください。手作業で既存コードのスタイルを修正してはいけません。その様な状況にある場合は、何もしないでください。
ClangFormatについては下記ページを参照してください。本ページに示すスタイルに合わせて整形するためのサンプル設定も掲載しています。
ファイル
- ファイルのエンコード
-
エンコードはUTF-8(BOMなし)とすべきです。近年、エンコードの標準はUTF-8となっています。バージョン管理ツールであるGitも、UTF-8を前提としています。非対応の処理系でない限り、UTF-8とすべきです。
- ファイル名
-
ファイル名はすべて小文字とし、単語間を「_」で区切ります。
例:file_process.c - 「.cファイル」には関連付く「.hファイル」を持たせる
名前
- 名前の長さに気を付ける
-
- 名前の長さの制限は処理系によって異なります。原則31文字以内とすること。
- 内部識別子(他のファイルから呼ばれない変数や関数)またはマクロ名において意味がある文字数は先頭63文字です。
- 外部識別子(他のファイルから呼ばれる変数や関数)において意味がある文字数は先頭31 文字です。
- 名前の英単語は極力省略しない
-
省略する場合は原則3文字以上とし、他の単語と混同しにくいものにしてください。
[例]
average → ave // 可 number → num // 可 number → no // 不可 (Yes/Noのnoと混同する)
変数
- 変数名
-
変数名はすべて小文字とし、単語間を「_」で区切ります。
[例]
count_max
- グローバル変数
-
グローバル変数は先頭に「g_」を付けます。なお「g」はglobalに由来します。
[例]
g_count_max
- 特定のファイルで定義した関数からのみアクセスする変数
-
特定のファイルで定義した関数からのみアクセスする変数は、ファイルスコープでstatic宣言して先頭に「m_」を付けます。なお「m」はmemberに由来します。
[例]
m_count_max
関数
- 関数名
-
関数名は単語の先頭を大文字とし、単語間を区切りません。ただし動詞とそれ以降の単語間は「_」で区切っても構いません。また慣習的な用法の場合は、先頭単語のみ小文字としても可とします。
CalcAverage, OpenFile Calc_Average, Open_File // 動詞との間を区切るのは条件付き可 isEditable // 真偽を問う慣習的表現のisは条件付き可
マクロ・定数
- マクロ名
-
マクロ名はすべて大文字で記述し、単語間を「_」で区切ります。
[例]
#define VALUE_MAX (100)
- 定数名
-
定数は先頭に「k」を付け、単語の先頭を大文字とし、単語間を区切りません。 なお「k」はドイツ語のkonstantに由来します。
[例]
const float kPi = 3.14159;
構造体・列挙型
- 構造体の定義
-
構造体は下記のように定義します。なお型名はすべて大文字で記述して単語間を「_」で区切り、メンバーは変数の命名規則にしたがうこと。
[例]
typedef struct { int mem1, // メンバー int mem2, ... } HOGE; // 型名
- 列挙体の定義
-
列挙型は下記のように定義します。なお型名はすべて大文字で記述して単語間を「_」で区切り、enum定数はマクロの命名規則にしたがうこと。
[例]
typedef enum { SUNDAY, // enum定数 MONDAY, ... } WEEK; // 型名
括弧
- 波括弧の開始は行末に書く
-
波括弧の開始は行末に書きます。ただし関数・構造体・共用体・列挙型の波括弧の開始は、行頭でも構いません。これはClangFormatの単一行表示の回避や、Doxygenの見栄えを考慮してのことです。
[不適合例]
void func(int arg1) { if (arg1 == 1) { ... } else { ... } }
[適合例]
void func(int arg1) { // 関数は行頭可 if (arg1 == 1) { ... } else { ... } }
- 制御文の波括弧は省略しない
-
[不適合例]
if (x > MAX) x = MAX; if (x > MAX) x = MAX; // 波括弧内にブレイクポイントを置けないので非推奨 if (x > MAX) { x = MAX; }
[適合例]
if (x > MAX) { x = MAX; }
- return文の戻り値は括弧で囲まない
-
[不適合例]
return (0);
[適合例]
return 0;
- ANDおよびOR演算子の左式と右式は括弧で囲う
-
[不適合例]
if (x == 0 && y == 0)
[適合例]
if ((x == 0) && (y == 0))
インデント・字下げ
- インデント
-
インデントは2スペースとします。またインデントはタブではなくスペースで行います。
- プリプロセッサ ディレクティブは行頭に書く
-
[不適合例]
void func(void) { ... #if DEBUG // インデント不可 ... #endif // インデント不可 }
[適合例]
void func(void) { ... #if DEBUG ... #endif }
- switch文のcaseは字下げしない
-
[不適合例]
switch (...) { case 0 : ... break; case 1 : ... break; default : ... }
[適合例]
switch (...) { case 0 : ... break; case 1 : ... break; default : ... }
改行・空行
- 1行の中に複数文を記述しない
-
[不適合例]
x = 0; y = 1; x = y = 0;
[適合例]
x = 0; y = 1;
- 空行
-
- 空行は最低限とし、2行以上の連続した空行は入れないこと。これはより多くのコードが1画面内に収まるようにするために重要なことです。
- 強く関連する処理は、間に空行やコメントを挟んではいけません。 逆に、異なる処理に入る際は空行を挟むこと。
空白
ここでは可読性を上げるために、一部の空白を「␣」と表します。
- 行末に空白を入れない
-
行末に空白を入れないこと。これは以降のどのルールよりも優先されます。
- 演算子の前後に空白を入れる
-
[不適合例]
y=a*x+b;
[適合例]
y␣=␣a␣*␣x␣+␣b;
- ポインターや参照の「*」や「&」の前に空白を入れる
-
[不適合例]
char*␣p;
[適合例]
char␣*p;
- 波括弧「{ }」の前後に続けて記述する場合、間に空白を入れる
-
[不適合例]
if (...){ ... }else{ ... }
[適合例]
if (...)␣{ ... }␣else␣{ ... }
- 括弧「( )」の内側には空白を入れない
-
[不適合例]
if (␣x == 0␣)
[適合例]
if (x == 0)
- 制御文に続く左括弧の前に空白を入れる
-
[不適合例]
if(x == 0) for(i = 0; i < 10; i++)
[適合例]
if␣(x == 0) for␣(i = 0; i < 10; i++)
- 関数宣言、呼び出しの左括弧の前には空白を入れない
-
[不適合例]
void func␣(void); func␣();
[適合例]
void func(void); func();
- 「,」や「;」の前後
-
- 「,」や「;」の後には空白を入れます。
- 「,」や「;」の前には空白を入れません。
[不適合例]
func(a␣,b␣,c)␣; for (i = 0␣;i < 10␣;i++)
[適合例]
func(a,␣b,␣c); for (i = 0;␣i < 10;␣i++)
- コメント
-
- 「//」の右側には空白を入れます。
- 「/* … */」の内側には空白を入れます。
[不適合例]
//AAA /*AAA*/
[適合例]
//␣AAA /*␣AAA␣*/
コメント
- コメントは「//」を使う
-
コメントは「//」の使用を推奨します。これは「/* … */」ではClangFormatによる位置揃えが働かないためです。
コメント