作業の分割

大規模なプログラムを作成するときは、複数人で協力しあいながら作業する 必要がある。そのときに必要な手順をまとめてみよう。

ソースの分割

大規模プログラミングには、分割 コンパイルが必須である。ひとつのファイルを大勢が同時にいじることはで きないので、意味あるかたまりごとに別々のファイルに分割し、それらを組み合わせて 完成品とする。

たとえば、以下のようなソースがあったとする。

#include <stdio.h>

typedef struct {
 char name[50];
 float  height;
 float  weight;
} human;

void taro(int x)
{
 ....
}
int hanako(human *y)
{
 ....
}

int main(int argc, char *argv[])
{
 human h;
 ...
 taro(3);
 x = hanako(&h);
}

これを分割する場合を考えよう。

上記プログラムを、太郎さんと花子さんで分担して作成する。 太郎さんは関数 taro() を、花子さんは関数 hanako() を作るものとする。

ヘッダファイル

複数のソースファイルから同じ構造体を使ったりする場合、 構造体定義など、共通の記述をヘッダファイルにまとめておく。

ヘッダファイルはファイル名が .h で終わるように名前をつける。

common.h

#include <stdio.h>
typedef struct {
 char name[50];
 float  height;
 float  weight;
} human;

void taro(int);
void hanako(human *);

このようにヘッダファイルには分割したファイル全てに共通な記述を まとめておく。これを別のCソースファイルから利用するには #include "ファイル名" 文を利用する。include 文は、<ファイル名> とするとヘッダファイルを /usr/include から探し、"ファイル名" とするとヘッダファイルをカレントディレクトリから探す。

taro.c

#include "common.h"
void taro(int x)
{
 /* 太郎さんが実際にいじる部分 */
 puts("taro.cの中のtaro()だよ");
}

hanako.c

#include "common.h"

void hanako(human *a)
{
  /* 花子さんが実際にいじる部分 */
  printf("%sさんの身長は%dcm, 体重は%.1fkgだよ\n",
         a->name, (int)(100*a->height), a->weight);
}

main.c

#include "common.h"

int main(int argc, char *argv[])
{
  int x=3;
  human h = {"公益太郎", 1.73, 65.2};
  taro(x);
  hanako(&h);
}

Makefile

ソースファイルを分割すると、コンパイル作業の負担が上がるので Makefile を作っておこう。

ターゲット:	[TAB文字] 依存しているファイル
[TAB文字]	作るためのコマンドライン

というルールを、全ての生成ファイルについて記述する。

Makefile

#
# Makefile for taro&hanako's program
#

# 最終目的物は taro-hanako
all:	taro-hanako

# taro-hanako は main.o taro.o hanako.o が材料で
taro-hanako:	main.o taro.o hanako.o
	gcc -o taro-hanako main.o taro.o hanako.o

# taro.o は taro.c と common.h に依存している
taro.o:		taro.c common.h
	gcc -c taro.c

# hanako.o は hanako.c と common.h に依存している
hanako.o:	hanako.c common.h
	gcc -c hanako.c

# main.o は main.c と common.h に依存している
main.o:		main.c common.h
	gcc -c main.c

目次