エディタを作る-1の5 ファイルの分割
特定の機能のみを集めて ソースファイルを分割する。
すると、ビルドの時間も短くて速くなる(変更していないファイルはコンパイルされないから)し、後々の移植や機能追加の際にも分かりやすくで 作業が楽になる。
欠点があるとすると、ソースファイルが(例えば main.cの1個)1ファイルだけで構成されていると、内容の解析作業などではシンプルで扱いやすい事が多い。 色々なファイルを検索しないと どこで定義されているのか分からない関数などが出て来ると、複数ファイルで構成されているプログラムは 結構 手間が掛かるからだ。
それを考慮に入れても「ファイル分割」は、メリットの方が大きい。
今回、「文字の色を変える」部分とその関連するコードを ファイル分割してみた。 分割開発の良い例だと思うので、丁寧に見て行こう。
まず、main.c から 「文字色 制御」に関連する部分を取り出す際に 気を付けなければならないのは、新たに作るファイルのファイル名だ。
ポイント1 ⇒ ファイル名はシンプルで 内容に合った命名を!
分かりやすいように Color.c とし、ここに ①画面の消去 ②文字色の変更 ③ 文字と背景色の変更 の 3つの関数を入れた。 これらが別のプロジェクトでも使えるだろう汎用的な機能だからだ。
これに伴い、Cソースファイルと同じ名称のヘッダーファイル Color.h を用意する。(ファイル拡張子 を .h にする)
ポイント2 ⇒ ファイル名と同じ名前のヘッダーファイルを作る
この中には 主に 関数のプロトタイプ宣言を書く。 そして、関数を使う側の(例えば main.c内)で include してあげるのは 云うまでも無い。
「プロトタイプ宣言」って何? といった初歩的な疑問は、自分で調べてください。
1)インクルード ガード
ヘッダーファイルが他のCソースファイル内で include される際に、何度も(無駄に)読み込まれるのを避けるために、ある仕掛けを行う。
これを一般的には「インクルード ガード」と呼ぶ。
/*++
* Module Name: Color.h
--*/
# ifndef _COLOR_H_
# define _COLOR_H_
・・・ ここに内容を書く ・・・
# endif //End of Color.h
通常は、ifndef と その endif に囲まれた中に 内容(関数のプロトタイプ等)を書くのだが、ヘッダーファイル名が Color.h だった場合、(私は)
_COLOR_H_
と、ファイル名を(すべて大文字にし)そのまま 使う事にしている。 文字列前後に アンダーバーを追加して(万が一の)重複をさけるようにして。
これが define定義されていなければ、初回のinclude なので、
#define _COLOR_H_
と 定義しそれ以下の内容を実行、次にincludeされても 2回目以降は実行され無いようにする。
ポイント3 ⇒ ヘッダーファイルには インクルードガードを付ける。
2)最近のインクルード ガード
ifndef と define を使っての インクルード ガードの手法は、古くから使い古されている方法なので いまさら解説するのも おこがましいが、これには欠点もある。
① define名が 他と重複することが (稀に)ある
② この仕組みだけで 最低3行も消費する
これらの問題を解消するために、最近では
#pragma once
が 使われる事がある。 これ1行さえ書いておけば、以下の内容は 二重に展開され無い・・・という便利なもの。
ただ、これが使える 開発環境(C言語)と、使えない開発環境が 今でも存在する。 よって、安全策で 今でも この古い方式を使う事にする。
3)ファイル分割の注意点
さて、「ファイル分割」を使ってのプログラム開発だが、ひとつ注意点がある。 これが便利と言われると、「馬鹿の一つ覚え」で やたらとファイルを細かく分けたがる人が出て来る。
よほどの理由(この部分だけは 後で絶対に修正が必要になるとか…)が無い限り、関数1つや2つの塊をファイル分割するべきでは無い。 今回は まだ開発途中なので Color.c 内は わずかなコードしかないが・・・ これも特殊な例の1つなので まだ しかたない。
ポイント4 ⇒ ファイル分割はせいぜい数個までに留める。
また、 極端に小さなファイルに分割しない
また、
ソースファイルの先頭に まったくコメントを書かない輩もいるが、せめて①ファイル名 ②製作開始日付 くらいは 書いておいた方が良い ③ 開発環境(言語名) や ④ OSの動く名前 ⑤変更履歴 なども書いておくに越した事は無い。 開発者名、会社名、コピーライトだの を長々と書き連ねるのは、逆に不要だろう。
そして、私の場合 ファイルの最後の行に、このファイルは「ここで終わりです」という意味のコメントを付ける事にしている。
// End of Color.c
その方が ソースを 印刷した時など 一目瞭然で分かりやすい。
(これは、ま~ お好きに どうぞ )
。