C言語-コーディング作法
コーディング作法とは
ソースコードは文章であり、他人が読むことを想定してわかりやすく記述する必要があります。
一般的に、ソースコードが存在する期間は、開発よりも保守期間のほうが長くなります。
将来にわたる保守性を損なわないようにソースコードを一貫性のある記述に統一する必要があります。
ソースコードを構造化して記述する、名前は処理やデータが類推可能なようにわかりやすくする、不要なコードやコメントを残さないといった工夫を行うべきといえます。
ネーミング(命名規約)
ネーミングとは、ソースコード内の関数や変数などの名前の付け方を指します。
ネーミングを統一することでコードの可読性が上がり、ケアレスミスによるバグの抑制やコードの保守容易性を高めることができます。
命名規約として「Indian Hillコーディング規約」や「GNUコーディング規約」などを参考にすることができます。
コードスタイル
命名規約とともに、コードの整形スタイルを統一することで可読性を向上することができます。
コードスタイルとしては「K&Rスタイル」、「BSDスタイル」や「GNUスタイル」があります。
UNIXならば「indentコマンド」を実行することでコードスタイルを統一変更することができます。
マジックナンバー
マジックナンバーとは、ソースコード中に直接記述された数値(即値)を指します。
マジックナンバーはソースコードの可読性を著しく損なう可能性があるため、名前のある値(マクロ、const変数、enum定数)を利用して明確化したほうがよいと言えます。
例えばhash_array[16]と記述するより、hash_array[HASH_ARRAY_MAX]と記述したほうが変数の意味が明確になります。
値を変更する際の容易性・保守性という観点からも、マジックナンバーは可能な限り置き換えをしたほうがいいと言えます。
構造化
論理をわかりやすくすることで、ソースコードの保守性を向上することができます。
ソースコードはモジュール単位に分割し、モジュールを構成する関数は短く簡潔に記述するべきといえます。
構造化プログラミング
C言語における構造化プログラミングとは、関数分割やソースファイル分割により、役割単位で分割してプログラミングする手法です。
ソースコードや関数の再利用を容易にする構成でプログラムを作成していきます。
関数の単位
関数は処理の単位として記述することを意識するべきです。
複雑な処理は、処理単位毎に関数として分類して記述することで、内部処理を類推しやすいようにします。
関数は処理内容を一目で判別できることを意識して、端末画面に収まるくらいの行数(80列30行を目安)で記述するべきです。
変数のスコープ
変数のスコープとは、変数を使用できるコードの範囲のことです。
変数のスコープを小さくすることで、予期しない値変更が発生しないように予防することができます。
プログラム中のどの位置からでも書き換え可能であるグローバル変数を使用することは必要最小限にするべきといえます。
変数について
変数の初期化
C言語では「静的変数」と「自動変数」の初期化の仕様が異なります。
静的変数(関数外で宣言された(グローバル)変数及び関数内の「static」指定した変数)は、明示的に初期化せずとも自動的に「0」(またはNULL)に初期化されます。
自動変数(関数内の「static」指定せずに宣言した変数)は、明示的に初期化しなければ、変数の値は不定です。
変数は適切に初期化してから利用しなければバグを発生させる要因となります。
変数のメモリ確保場所
C言語では変数の種類によって確保されるメモリの場所が異なります。
各領域の容量上限はOSに依存します。
自動変数 | スタック領域 |
動的メモリ確保(mallocなど) | ヒープ領域 |
静的変数 | データ領域 |
メモリ解放
freeされた領域のポインタを再度freeした場合、不正動作を起こす可能性があります。
C言語ではNULLポインタに対するfreeはプログラムの実行に影響を及ぼさないことが保証されています。
解放したポインタ変数にはNULLを代入するようにプログラムを記述することで、バグの発生を低減することができます。