雑知識
訪問数 1536   最終更新 2009-06-18 (木) 17:29:26

2009-06-18 分割コンパイルとmake 〜 例題ベースで

ここでは、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が、 入るようにしてください。

bunkatsu_compile.png

それぞれのファイルをコンパイルしてみましょう。複数のファイルに分割されたプログラムをコンパイルするとき(分割コンパイルと呼ばれる)は、図のように、それぞれのファイルを別々にコンパイルしておいて、最後に一緒にします。

さて、うまくコンパイルが出来たでしょうか?

次へ


添付ファイル: filebunkatsu_compile.png 755件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2009-06-18 (木) 17:29:26 (4761d)