大規模なプログラムを作成する際, 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);
}