モジュール化設計

「C言語関係の役立ちリンク」からもリンクを張っていますが、 「つくる人の味方」 分割コンパイル などweb上にいろいろも分かりやすく解説したページがあるのでそれも参考にしてください。

数値計算用のプログラムを作成する際、一つのファイルに全ての処理を記述していると ソースコードが長くなるにつれ、取り扱いが困難になってきます。 その場合、いくつかのファイルに分けて制作することが重要になります(これをプログラム のモジュール化と呼びます)。

また、ファイル単位だけでなく、ある機能や処理を行う関数群や 関数単位またはデータ群などを、他のものとは独立して閉じた形で扱えるように 構成することなども意味します。以下でも、ファイル分割だけではなく、 より一般的な後者の意味でのモジュール化について説明します。

ファイル単位のモジュール化の実際については「分割コンパイル」や「Makefile」 を参照のこと。

モジュール化の利点

たとえば、適当なベンチマーク問題(さまざまサイズの問題がファイルで与えられているとします。) を解く数値計算プログラム作成を考えます。 ます、ベンチマーク問題のファイルをロードし、適当なパラメータもとで、アルゴリズムを開始し、 得られた結果を画面表示するプログラムを考えましょう。 プログラムは大きく分けて、データファイル読み込みモジュール、アルゴリズム本体のモジュール 画面表示モジュールという 3 つの単位に分ける事ができます。 プログラムの処理単位ごとに分割したソースファイルを制作し、プログラム開発やデバッグなどを 個別に行う事ができます。 これにより、分割コンパイルが行えるので、ソースコードすべてをコンパイルする手間が省けます。

また、作成しようとしているプログラムが、提案法3種、従来法2種を用いた5種類ある場合、 「アルゴリズム本体」の部分を、差し替えることができます。 このように、共通するモジュールをいくつかのプログラムで共有できます。 また、そのようにモジュール化されたプログラムであれば、それが他のユーザが作成したもので あっても自分のプログラムに自由に組み合わせることもできます。

関数、変数の隠蔽

モジュール化にあたって、さらに大事なことは、単に処理が同じ関連する関数群をまとめること だけではなく、処理されるデータや関数を

に分けることです。 モジュール内だけで扱う関数、変数は、static 修飾子を使用してモジュール内部 に隠蔽します。 また、外部とやり取りする関数、変数は、必要最小限に押さえておきます。 そうしておけば、隠蔽された機能の変更は、モジュール内だけに影響を抑えられますので、 修正が楽に行えますし、モジュールを丸ごと入れ替えるのも簡単です。 さらに、他人の作ったモジュールでも、外側からアクセスする関数の動作や変数にだけ気を つけておけば、その機能を知っていれば問題なく使用できます。 逆に、何を公開して何を隠蔽するかという設計は、 プログラムの修正や変更なども考慮したプログラミング全体の設計にかかわりますので 前もって熟考する必要が有ります。

グローバル変数について

上記のようにモジュール化した場合、いくつものモジュールに共通して使用する大域変数(グローバル変数) は、そのままでは使用できません(関数の引き数として受渡をしていないものとします)。 モジュール単位を各ファイルごとの分割と考えた場合、いくつかのファイルで共通に使用するには extern を用いれば可能になりますが、これは極力避けてください。 大域変数を用いると上述のモジュール化の利点が 大いに失われる可能性があります。 修正に対して関数ほど融通が利きません。なるべく大域変数を使わないで、代わりに値を返したり設定した りする公開された関数を使用するようにしてください。

受渡するデータ数が増えてくる場合は、構造体を利用してポインタ渡しを 使えば楽に関数に渡せます。ここでも、どのような変数を一まとまりと 考えるかということは、上記モジュール化の重要な決定項目と成ります。

注意点

モジュール化は、各々の機能を独立させるため、プログラムソースの見通しがよくなりますが、 汎用性のありすぎる関数を多く用いてモジュール化しすぎると、実行速度が遅くなったり、メモリー を多量に消費する可能性があります。 美しくモジュール化することと、実行速度、メモリー使用量などは トレードオフの関係になることがありえます。

データ構造を生かして、計算時間を短縮できる計算、メモリー領域を小さくできる格納法がある場合は、 規模が大きい場合など、そういった特性を生かした関数、データ構造を利用して計算、格納すること。 その場合、

の対応は、必ずしも一致しないことに注意してください(一致しているに越したことはありませんが)。 上記のいくつかの観点から鑑みて関数、変数等のモジュール化の設計をするひつようがあります。

その他数値計算のTIPS(別のページに書いたほうがいいかもしれませんね)

大きなデータ領域の確保、解放を繰り返さない。大規模な問題の時は、同時に大きなデータ領域 を作らないこと。ポインタ渡しで済む場合に、代入等を行わない。

ある関数内で触れないはずの変数はconst をつける。 #define を使わずにconst int を使用