大規模なプログラムを作成する際, 1個の巨大なソースファイルのまま編集すると, 余計な手間・時間が費やされがちとなる. 複数の小さなファイルに分割し, 作業を楽にしよう.
未完成です... とりあえず こちら (昨年度の授業内容)を参考に学習してください.
pendraw.c を複数のソースファイル・ヘッダファイルに分割せよ.
まず安全のための準備として, 前回作成(したハズ)の2個のソースファイル pdcl.c(マクロ導入済み)と pendraw.c(構造体導入済み)とを ディレクトリ pendraw/ 内にコピーしておこう. そして,この問題の作業については, すべてこのディレクトリの中で実施しよう:
$ mkdir pendraw/ $ cp ../c-1113/pdcl.c ./pendraw/ $ cp ../c-1113/pendraw.c ./pendraw/ $ cd pendraw/
目標とする分割ソースファイルの構成:
$ ls img.c img.h main.c pdcl.c # 今回,このファイルの内容は変更しません pen.c pen.h $ cat img.h #ifndef IMG_H #define ... typedef struct { ... } Img; extern void FillImg(...); extern void ShowImg(...); #endif ... $ cat img.c #include ... void FillImg(...) { ... } void ShowImg(...) { ... } $ cat pen.h #ifndef PEN_H #define ... typedef struct { ... } Pen; extern void ShowPen(...); extern void Draw(...); extern void Ctrl(...); #endif ... $ cat pen.c #include ... void ShowPen(...) { ... } void Draw(...) { ... } void Ctrl(...) { ... } $ cat main.c #include ... int Info(...) { ... } int Game(...) { ... } int Title(...) { ... } int main(...) { ... }
pendraw の一括コンパイル:
$ cc img.c pen.c main.c -lncurses -o pendraw -Wall
pendraw の分割コンパイル:
$ cc -c img.c -Wall $ cc -c pen.c -Wall $ cc -c main.c -Wall $ cc img.o pen.o main.o -lncurses -o pendraw
pdcl の一括コンパイル:
$ cc pdcl.c -o pdcl -Wall
pendraw の構造体変数 img について...
img.c:
... // 画像のメモリ領域を開放する関数 void FreeImg(Img *img) { if (img == NULL) return; if (img->pixel != NULL) free(img->pixel); free(img); } // 画像のメモリ領域を確保する関数 Img *NewImg(int w, int h) { Img *img; img = (Img *)malloc(sizeof(Img)); // 軌跡画像構造体のメモリを確保 if (img == NULL) return (NULL); img->w = w; img->h = h; img->pixel = (char *)malloc(sizeof(char)*w*h); // 軌跡画像配列のメモリを確保 if (img->pixel == NULL) { free(img); return (NULL); } return (img); } ...
main.c:
... int Game(...) { ... Img *img; /* 画像構造体の操作をすべて関数化したし, 構造体引数は参照渡しとすべきなので, 画像構造体をすべてポインタとして使うことにする. これに伴い,&img の部分をすべて img に変更必要. */ ... img = NewImg(w, h); if (img == NULL) goto ERROR; FillImg(img, ' '); ... FreeImg(img); }