最小限の分割
複数ファイルを使う理由
これまでプログラムを記述する時には、エディタのウィンドウに書き込んできましたが、
その時、常に1つの画面の中にすべてのプログラムを記述してきました。
つまり、1つのファイルの中にすべてのプログラムを記述してきたことを意味します。
この方法は単純なので、規模の小さなプログラムでは有効な方法です。
しかし、規模が大きなプログラムでは、1つのファイルにすべてを書き込んでいると、
どこにどのプログラムがあるのかがわかりにくくなります。
さらに、何人かで1つのプログラムを作ろうとする場合には、
1つのファイルに2人以上の人が同時に書き込むことは基本的に不可能なので、
2人以上でのプログラミングは事実上不可能になってしまいます。
この問題の解決には、複数のファイルに分割してプログラムを書く必要があります。
複数のファイルに分割することで、どこにどのプログラムがあるのかわかりやすくなり、
また、何人かで1つのプログラムを作ることも可能になります。
その時、常に1つの画面の中にすべてのプログラムを記述してきました。
つまり、1つのファイルの中にすべてのプログラムを記述してきたことを意味します。
この方法は単純なので、規模の小さなプログラムでは有効な方法です。
しかし、規模が大きなプログラムでは、1つのファイルにすべてを書き込んでいると、
どこにどのプログラムがあるのかがわかりにくくなります。
さらに、何人かで1つのプログラムを作ろうとする場合には、
1つのファイルに2人以上の人が同時に書き込むことは基本的に不可能なので、
2人以上でのプログラミングは事実上不可能になってしまいます。
この問題の解決には、複数のファイルに分割してプログラムを書く必要があります。
複数のファイルに分割することで、どこにどのプログラムがあるのかわかりやすくなり、
また、何人かで1つのプログラムを作ることも可能になります。
ソースとヘッダーファイル
プログラムを複数のファイルに分割するとなるとなにやら難しそうですが、
実は、最初から無意識の内に分割してプログラムを作っていたのです。
printf関数などを使うには、#include <stdio.h> を先頭に記述する必要がありました。
実は、これこそがプログラムを複数のファイルに分割するということです。
#include疑似命令は、指定されたファイルの内容を取り込むという命令です。
そして、stdio.h は、printf関数などのさまざまな関数の宣言を含んでいます。
ここで重要なことは、stdio.h には、printf関数の宣言だけが書かれているだけであり、
実際のプログラムは、stdio.h の中には書かれていないと言うことです。
printf関数の実際のプログラムは、stdio.h とは別のファイルに記述されています。
stdio.h のような、宣言だけが書かれたファイルをヘッダーファイルと呼びます。
ヘッダーファイルには、拡張子として、.h をつけることが慣習となっています。
関数や変数の宣言のみが記述されたファイル。
拡張子は .h にすることが慣習となっている。
これに対して、実際にプログラムを記述するファイルをソースファイルと呼びます。
今までに記述してきたのはすべてソースファイルです。なお、拡張子は .c とします。
プログラムが記述されたファイル。
拡張子は .c にすることが慣習となっている。
ソースファイルとヘッダーファイルは、通常、1対1で対応するように作成します。
ソースファイルの中から宣言の部分を抜き出して、
同じ名前(拡張子だけ変える)にして、ヘッダーファイルを作成します。
実は、最初から無意識の内に分割してプログラムを作っていたのです。
printf関数などを使うには、#include <stdio.h> を先頭に記述する必要がありました。
実は、これこそがプログラムを複数のファイルに分割するということです。
#include疑似命令は、指定されたファイルの内容を取り込むという命令です。
そして、stdio.h は、printf関数などのさまざまな関数の宣言を含んでいます。
ここで重要なことは、stdio.h には、printf関数の宣言だけが書かれているだけであり、
実際のプログラムは、stdio.h の中には書かれていないと言うことです。
printf関数の実際のプログラムは、stdio.h とは別のファイルに記述されています。
stdio.h のような、宣言だけが書かれたファイルをヘッダーファイルと呼びます。
ヘッダーファイルには、拡張子として、.h をつけることが慣習となっています。
キーワード
【ヘッダーファイル】
関数や変数の宣言のみが記述されたファイル。
拡張子は .h にすることが慣習となっている。
これに対して、実際にプログラムを記述するファイルをソースファイルと呼びます。
今までに記述してきたのはすべてソースファイルです。なお、拡張子は .c とします。
キーワード
【ソースファイル】
プログラムが記述されたファイル。
拡張子は .c にすることが慣習となっている。
ソースファイルとヘッダーファイルは、通常、1対1で対応するように作成します。
ソースファイルの中から宣言の部分を抜き出して、
同じ名前(拡張子だけ変える)にして、ヘッダーファイルを作成します。
最小限のヘッダーファイル
前項では、ヘッダーファイルの意味について説明しました。
ここでは、実際に最低限の構成でヘッダーファイルとソースファイルを作成し、
第11章で作成したsum関数を分割してみたいと思います。
まずは、sum関数を含むソースファイル、sum.cを作成してみます。
これは簡単なことで、[第11章](11-03,html)で作成したsum関数をコピーするだけです。
次に、sum.c 内に含まれる関数を他のソースファイルから使えるようにするために、
sum.c から宣言部分を抜き出して、ヘッダーファイル sum.h を作成します。
sum.c 内に含まれる宣言はsum関数の宣言だけなので、これを記述します。
これで、sum関数の分割は完了しました。
しかし、これではmain関数がないので、プログラムを実行できません。
そこで、main関数を含むソースファイル、main.c を作成します。
main.c の記述もほとんど第11章と同じですが、1つ異なる点があります。
今回、sum関数のプロトタイプ宣言は、sum.h に記述しているので、
sum.h を取り込まない限り、sum関数を使うことができません。
sum.h を取り込むのには、当然、#include疑似命令を使用します。
ただし、今まではヘッダーファイル名を <> で囲んでいたのですが、
自分で作成したヘッダーファイルを取り込むには、"" で囲むことになっています。
なお、#include疑似命令でヘッダーファイルを取り込むことを、インクルードと言います。
#include疑似命令でヘッダーファイルを取り込むこと。
これで、main.c も完成です。
なお、main.c のヘッダーファイル、main.h は作成する必要はありません。
main.c 内に含まれる関数を他のソースファイルから使う必要はないからです。
さて、早速コンパイルして実行してみたいのですが、このままではコンパイルできません。
今まではエディタの機能によって、1つのファイルであれば自動的に指定されたのですが、
2つ以上のファイルを使う場合には、使うファイルを指定する必要があります。
設定は使用しているコンパイラによって多少異なります。
この様に別のファイルに分けておくようにすれば、sum関数を直接書き込まなくても、
sum.h と sum.c のファイルをコピーして、先頭で #include "sum.h" とするだけで、
sum.c 内に含まれる関数をすべて利用できます。
sum.c 内の関数がある場合を同じファイルにコピーするよりもすっきりしますし、
関数の名前と引数さえ決めておけば、他の人にその関数を作ってもらって、
ファイルを送ってもらって、あとで一緒にコンパイルするという、多人数開発も実現できます。
まあ、現代ではGit一択ですので、そんなことはしないのですが・・・
ここでは、実際に最低限の構成でヘッダーファイルとソースファイルを作成し、
第11章で作成したsum関数を分割してみたいと思います。
まずは、sum関数を含むソースファイル、sum.cを作成してみます。
これは簡単なことで、[第11章](11-03,html)で作成したsum関数をコピーするだけです。
sum.c
/* sum.c */
int sum(int min, int max)
{
int num;
num = (min + max) * (max - min + 1) / 2;
return num;
}
次に、sum.c 内に含まれる関数を他のソースファイルから使えるようにするために、
sum.c から宣言部分を抜き出して、ヘッダーファイル sum.h を作成します。
sum.c 内に含まれる宣言はsum関数の宣言だけなので、これを記述します。
sum.h
/* sum.h */
int sum(int min, int max);
これで、sum関数の分割は完了しました。
しかし、これではmain関数がないので、プログラムを実行できません。
そこで、main関数を含むソースファイル、main.c を作成します。
main.c の記述もほとんど第11章と同じですが、1つ異なる点があります。
今回、sum関数のプロトタイプ宣言は、sum.h に記述しているので、
sum.h を取り込まない限り、sum関数を使うことができません。
sum.h を取り込むのには、当然、#include疑似命令を使用します。
ただし、今まではヘッダーファイル名を <> で囲んでいたのですが、
自分で作成したヘッダーファイルを取り込むには、"" で囲むことになっています。
なお、#include疑似命令でヘッダーファイルを取り込むことを、インクルードと言います。
キーワード
【インクルード】
#include疑似命令でヘッダーファイルを取り込むこと。
main.c
/* main.c */
#include "sum.h"
#include <stdio.h>
int main(void)
{
int value;
value = sum(50, 100);
printf("%d\n", value);
return 0;
}
これで、main.c も完成です。
なお、main.c のヘッダーファイル、main.h は作成する必要はありません。
main.c 内に含まれる関数を他のソースファイルから使う必要はないからです。
さて、早速コンパイルして実行してみたいのですが、このままではコンパイルできません。
今まではエディタの機能によって、1つのファイルであれば自動的に指定されたのですが、
2つ以上のファイルを使う場合には、使うファイルを指定する必要があります。
設定は使用しているコンパイラによって多少異なります。
学習用C言語開発環境での設定
とくに設定はいりません。
メニューからファイルを追加すれば、自動的に認識されるようになっています。
メニューからファイルを追加すれば、自動的に認識されるようになっています。
Visual Studio での設定
とくに設定はいりません。
プロジェクトにファイルを追加すれば、自動的に認識されるようになっています。
プロジェクトにファイルを追加すれば、自動的に認識されるようになっています。
Borland C++ Compiler と Visual C++ Toolkit 2003 の設定
メニュー -> 実行 -> コンパイル時パラメータ を選択し、
コンパイル時パラメータの欄に、
-emain main.c sum.c
と打ち込みます。
-emain とは、実行ファイルを main.exe と言う名前で作成させる命令です。
後半の2つは、共にコンパイルするソースファイル名を指定しています。
ヘッダーファイルはソースファイルでインクルードしているので不要です。
コンパイル時パラメータの欄に、
-emain main.c sum.c
と打ち込みます。
-emain とは、実行ファイルを main.exe と言う名前で作成させる命令です。
後半の2つは、共にコンパイルするソースファイル名を指定しています。
ヘッダーファイルはソースファイルでインクルードしているので不要です。
stdio.hの時は設定不要
今までにも、stdio.h などにより無意識の内に複数ファイルに分割していたのですが、
その時は、コンパイラが自動的に設定していたので、
今回のように他のファイルを指定する必要などはありませんでした。
その時は、コンパイラが自動的に設定していたので、
今回のように他のファイルを指定する必要などはありませんでした。
この様に別のファイルに分けておくようにすれば、sum関数を直接書き込まなくても、
sum.h と sum.c のファイルをコピーして、先頭で #include "sum.h" とするだけで、
sum.c 内に含まれる関数をすべて利用できます。
sum.c 内の関数がある場合を同じファイルにコピーするよりもすっきりしますし、
関数の名前と引数さえ決めておけば、他の人にその関数を作ってもらって、
ファイルを送ってもらって、あとで一緒にコンパイルするという、多人数開発も実現できます。
まあ、現代ではGit一択ですので、そんなことはしないのですが・・・
本サイトについて
苦しんで覚えるC言語(苦C)はC言語入門サイトの決定版です。
C言語の基本機能を体系立てて解説しており、
市販書籍と同等以上の完成度です。




