WisdomSoft - for your serial experiences.

8.1 インクルード

コンパイル前に処理される #include プリプロセッサディレクティブを用いることで、宣言などをまとめたヘッダファイルを任意のソースファイルに埋め込めます。これをインクルードすると呼びます。

8.1.1 ヘッダファイルの作成

複数のファイルで構成される中規模以上の開発プロジェクトでは、プログラム方法だけではなく、ファイルの構成なども重要になってきます。本書で扱っているような小さな実験用プログラムであればひとつのファイルで十分作成することができますが、実践ではそうはいきません。開発メンバーは一人ではありませんし、あるグループはグラフィックス、別のグループでは音声といった異なる分野の開発を同時進行で行う可能性が十分にあります。そして、これらは単一のファイルで行うことはできません。

論理的に区分けされた機能をファイルごとに分割して開発を進めるような場合は、最終的にひとつにまとめてコンパイルを行う必要があります。通常、main() 関数を含む実行ファイルを作成するためのソースファイルは拡張子を *.c としますが、それ以外のライブラリとしての役割を持つ関数セットを提供するファイルは、ヘッダファイルとして *.h を拡張子とする習慣があります。ヘッダファイルは main() 関数よりも前に挿入されます。

複数のファイルをひとつにまとめてコンパイルするには、#include プリプロセッサディレクティブを使ってファイルの指定した位置にヘッダファイルを挿入するようにコンパイラに伝えます。コンパイラは #include を発見すると、この位置に指定したファイルを挿入します。これまでは #include <stdio.h> と記述することで C 言語が標準でサポートするライブラリファイルを結合してきました。これをインクルードすると表現します。

標準ファイル以外のインクルードには #include "ファイル名" というように二重引用符で囲んで記述します。これは「2.2 はじめてのC言語」で解説しています。コンパイラがどのようにファイルを検索するかは、コンパイラのドキュメントを参照してください。二重引用符で囲まれている場合は、通常 *.c ファイルと同じディレクトリから検索されます。

インクルードは、単純にファイルの挿入と考えてください。この # で始まる命令は、コンパイラではなく、プリプロセッサに対する命令です。プリプロセッサは、ソースがコンパイルされる前に実行されます。#include はファイルを挿入するという命令なので、コンパイラがソースをコンパイルする前に指定位置にファイルの内容をそっくりそのまま挿入するのです。そのため、開発者はヘッダファイルに汎用的な関数などを記述し、これをプロジェクトの C ソースファイルにインクルードするのです。そうすれば、同じ関数を何度も書く作業から解放されます。

コード1
/* sample.h */
int strlen(const char *str);

コード2
int strlen(const char *str) {
	int count;
	for(count = 0 ; *(str + count) ; count++);
	return count;
}
コード3
#include <stdio.h>
#include "sample.h"

int main() {
	char *str = "Kitty on your lap";
	printf("%s length=%d\n" , str , strlen(str));
	return 0;
}
実行結果
コード2 実行結果

ヘッダファイルのコード1を作成し、これをコード3でインクルードしてコンパイルを行います。すると、#include "sample.h" と記述した場所に、ヘッダファイルの内容がそのままコピーされ、コンパイルされます。コード1では NULL 文字を除く文字列の文字数を返す strlen() 関数を宣言しています。strlen() 関数の実装はコード2に記述しています。このようなヘッダファイルを一度作れば、全ての開発プロジェクトで再利用できるのです。