![]() |
分割コンパイルとmakehttp://pepper.is.sci.toho-u.ac.jp/pepper/index.php?%CA%AC%B3%E4%A5%B3%A5%F3%A5%D1%A5%A4%A5%EB%A4%C8make |
![]() |
雑知識
訪問数 1536 最終更新 2009-06-18 (木) 17:29:26
ここでは、C言語のプログラムを複数のファイルに分割したときに、 何が起こるかを理解してください。
次のようなプログラムを、2つのファイルに分割してください。1つ目のファイル main.c には関数mainが、2つ目のファイル util.c には関数initializeと関数fが、 入るようにしてください。
このプログラム自身はたいした意味はありません。数値積分(区分求積)の台形法で、 f(x) = sqrt ( 1 - x*x ) (つまり x*x + y*y = 1 ) のうちx, yとも区間[0,1]の 部分について積分したものです。
分割がややこしくなるように、わざと(1)構造体init_struct init_dataを用意 しました。こんなことはしなくて済むのですが、敢えて構造体を使っています。 また(2)初期化の関数initializeを設けました。これも必要ないのですが、 ファイル分割をおもしろくするために設けました。
# Program Sample 1 #include <stdio.h> #include <math.h> /* 関数sqrtを使うために必要 */ struct init_struct { int n; /* 積分区間の分割数、initializeで適当な値にセット */ double start; /* 積分範囲の開始点、initializeで0.0にセット */ double end; /* 積分範囲の終了点、initializeで1.0にセット */ double h; /* 台形の高さ、initializeで1/nにセット */ }; struct init_struct init_data; /* 敢えて構造体宣言と構造体変数宣言を分けた */ double f(double x) { /* 円の関数 */ return( sqrt( 1.0 - (x*x) ) ); } void initialize() { /* init_dataのn, start, end, hを設定 */ init_data.n = 10000000; init_data.start = 0.0; init_data.end = 1.0; init_data.h = (init_data.end - init_data.start ) / (double) init_data.n; } int main() { int i; double sum = 0.0; initialize(); for (i=1; i<=init_data.n-2; i++) { /* 区間の両端を除いた点のf(x)を累積 */ sum = sum + f( (double)i * init_data.h ) ; } sum = sum + 0.5 * ( f(init_data.start) + f(init_data.end) ); /* 区間両端は1/2分ずつ累積 */ printf("%20.17f\n", ( 4.0 * sum * init_data.h ) ); /* 高さhを掛け、4倍して半径1の円の面積 */ }
まず、これ全体をex1.cというファイルにして、コンパイルし (gcc -o ex1 -lm ex1.c) 、実行できるか確認してください。
さて、分割してみてください。1つ目のファイル main.c には関数mainが、 2つ目のファイル util.c には関数initializeと関数fが、 入るようにしてください。
それぞれのファイルをコンパイルしてみましょう。複数のファイルに分割されたプログラムをコンパイルするとき(分割コンパイルと呼ばれる)は、図のように、それぞれのファイルを別々にコンパイルしておいて、最後に一緒にします。
さて、うまくコンパイルが出来たでしょうか?