翻訳単位
スポンサーリンク
ソースファイルに前処理を施した単位を,翻訳単位 (translation unit) と言います。
次のプログラムは,複数の翻訳単位から成るプログラムの例です。
tree.h, tree.c には,2 分木に関係するユーザ定義型や関数が定義されています。
main.c では,右図の 2 分木の高さを求めています。
/* tree.h */
/* 2 分木のノードを表す構造体 */
typedef struct node {
int value;
struct node *left, *right;
} Node, *Tree;
/* 2 分木の高さを返す関数 */
int height(Tree);
/* tree.c */
#include "tree.h"
int height(Tree t)
{
int l = 0, r = 0;
if (t->left) l = height(t->left) + 1;
if (t->right) r = height(t->right) + 1;
return l > r ? l : r;
}
/* main.c */
#include <stdio.h>
#include "tree.h"
int main(void)
{
Node a, b, c;
a.value = 1; a.left = &b; a.right = NULL;
b.value = 2; b.left = NULL; b.right = &c;
c.value = 3; c.left = NULL; c.right = NULL;
printf("%d\n", height(&a)); /* 出力: 2 */
return 0;
}
分割コンパイル
C のソースファイルは,上図の工程を経て実行可能ファイルにコンパイルされます。
大規模なプログラムでは,前処理,(狭義の) コンパイルと,リンクとを別々に行う,分割コンパイルが行われます。
GCC で上記プログラムを分割コンパイルする実行例を次に示します。
% ls
hoge.c piyo.c piyo.h
% gcc -c hoge.c
% gcc -c piyo.c
% ls
hoge.c hoge.o piyo.c piyo.h piyo.o
% gcc hoge.o piyo.o
% ls
a.out hoge.c hoge.o piyo.c piyo.h piyo.o
関数プロトタイプの役割
ヘッダファイルには,関数のプロトタイプ宣言を始め,定数や構造体などの定義が書かれます。
関数のプロトタイプ宣言は,コンパイラが型のチェックを行うために必要です。
上のプログラムでは,関数 func2 に誤った型の引数を渡していますが,関数プロトタイプがないため,コンパイラはその誤りを発見できません (関数プロトタイプがないとの警告は出ます)。
インクルードガード
ヘッダファイルが多重にインクルードされるのを防ぐため,しばしばヘッダファイルの内容全体を #ifndef - #endif で防護することがあります。
#ifndef _HOGE_H_
#define _HOGE_H_
/* ヘッダファイルの内容 */
#endif
スポンサーリンク