目次
ファイル分割のメリット
ソースコードが長くなると関数に分けていてもコードを読むのが大変になります。
そんな時、ソースコードを分割することで読み易く、整理しやすいコードにすることができます。
また、複数人でコーディングを行うとき必須になります。
何故なら、複数人で一つのファイルを同時に編集するのは難しいためです。
分割の方法
ソースコードの分割に難しい仕組みの理解は必要ありません。
いつも使っている、#include文を用います。
#include文はインクルードしたファイルに記述されいる内容をそのファイルでも使えるようにする構文です。
例えば、インクルードしたファイルにグローバル変数が定義されていれば、#include文を書いたファイルでもそのグローバル変数を使えるようになります。また、インクルードしたファイルで別のファイルをインクルードしていれば、そこに書いてある内容も使うことができます。
因みに、拡張子「.h」のヘッダファイルも中身はC言語のプログラムです。
しかし、一般的にはヘッダファイルには変数や関数の定義を書きません。
別の「.c」のファイルに記述した内容をextern宣言を用いて使えるようにします。
サンプル
実際にソースファイルを分割する例を見ていきましょう。
以下のファイルを分割します。
main.c
#include <stdio.h> double num = 10; double get_ave(int arr[], int arr_max) { int i; int sum = 0; for (i = 0; i < arr_max; i++) sum += arr[i]; return sum / arr_max; } int main(void) { int arr[MAX_ARRAY] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; double ave; ave = get_ave(arr, MAX_ARRAY); if (ave != num) { printf("hello, world."); } getchar(); return 0; }
main.cにはグローバル変数と関数がそれぞれ一つあります。また、外部ファイルとしてstdio.hをインクルードしています。
これらを分割して複数のファイルに分けましょう。
分割したファイルが以下の3つになります。
main.c
#include "myHeader.h" int main(void) { int arr[MAX_ARRAY] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; double ave; ave = get_ave(arr, MAX_ARRAY); if (ave != num) { printf("hello, world."); } getchar(); return 0; }
func_def.c
#include "myHeader.h" double num = 10; double get_ave(int arr[], int arr_max) { int i; int sum = 0; for (i = 0; i < arr_max; i++) sum += arr[i]; return sum / arr_max; }
myHeader.h
#pragma once #include <stdio.h> #define MAX_ARRAY 10 extern double num; extern double get_ave(int arr[], int arr_max);
stdio.hはmyHeader.hでインクルードし、myHeader.hをインクルードすることでmain.cとfunc_def.cの両方でstdio.hを使えるようにしています。
グローバル変数と関数は定義をfunc_def.cに記述し、myHeader.hでextern宣言することでmain.cでも使えるようにしています。
myHeader.hの1行目の#pragma onceは重複インクルードを禁止する構文です。main.cとfunc_def.cの両方でmyHeader.hをインクルードしているので両方実行すると二重インクルードとなるため必要になります。
ファイルを分割することで、ファイル一つひとつの可読性が向上していることがわかるでしょう。このサンプル程度の短いプログラムならあまり必要ありませんが、大規模なプログラムを書く場合には、読み易さと複数人での作業分担の面でもファイルの分割が役に立ちます。
このサンプルでは省いていますが、構造体や列挙体の定義もヘッダファイルに記述することで共有が出来ます。