[[雑知識]]~
訪問数 &counter(); 最終更新 &lastmod();~
> [[分割コンパイルとmake]]~
> [[分割コンパイルとmakeその2]]
**分割コンパイルとmake その3 [#xf6d51f6]
***分割コンパイルとmake その3 [#xf6d51f6]
構造体の形の定義
struct init_struct {
int n;
double start;
double end;
double h;
};
は、同じものを main.c と util.c に置かなければなりません。この構造体の形をいじりたい(たとえばメンバーを増やしたい)とき、必ず両方のファイルで正しく変更しなければなりません。もし、ソースファイルが2つではなくて何十もあったらどうなるでしょうか?変更を間違いなく、抜けの無いようにすることは、とても大変です。
そこで、ヘッダーファイルに書くことで共通に利用することを考えます。たとえばファイル init.h として
init.h
struct init_struct {
int n;
double start;
double end;
double h;
};
を用意したとします。(仮に、main.cやutil.cと同じディレクトリ内に置くとします。)これをmain.cやutil.cに取り込むには、#include "init.h" とします。よく使うincludeの引数は<stdio.h>のように三角カッコで囲んでいましたがこれはシステムの所定のディレクトリ(たとえば/usr/include/の下)に置いている場合です。main.cなどと同じディレクトリに置いている場合は、二重引用符で"init.h"のように囲います。
さて、main.c、 util.cは次のようになります。
util.c main.c
#include <stdio.h> | #include <stdio.h>
#include <math.h> |
#include "init.h" <<<ここに追加 | #include "init.h" <<<ここに追加
|
extern struct init_struct init_data; | struct init_struct init_data;
|
| double f(double x);
| void initialize();
|
double f(double x) { | int main() {
return(sqrt(1.0-(x*x))); | int i;
} | double sum = 0.0;
|
void initialize() { | initialize();
init_data.n = 10000; |
init_data.start = 0.0; | for (i=1; i<=init_data.n-2; i++) {
init_data.end = 1.0; | sum=sum+f((double)i*init_data.h);
init_data.h = | }
(init_data.end-init_data.start)/ |
(double)init_data.n; | sum = sum + 0.5*
} | (f(init_data.start)+f(init_data.end));
| printf("%20.17f\n",(4.0*sum*init_data.h));
| }
ここで注意しなければならないのは、ヘッダーファイルの中に、グローバル変数の宣言を書いてはまずい、ということです。当たり前ですが、init.hはmain.cとutil.cの両方でincludeされています。つまり、両方のファイルにその内容が書き足されているわけで、もしグローバル変数の宣言を書くと、その宣言は両方のファイルに置かれたことになって、2回(重複して)宣言されたことになります。だから、共通に取り込むヘッダーファイルは、形の宣言(型宣言とか構造体の形の宣言、関数のプロトタイプ宣言)は含んでよいが、変数の宣言を含めてはまずい、ということです。あと、ヘッダーファイルにはよく#defineが含めてあります。 サンプルとして/usr/includeの下のいろいろなヘッダーファイルを見てみると勉強になります。
[[その次〜make>分割コンパイルとmakeその4]]