ヘッダファイルとは,定数の宣言,構造体の宣言,関数の宣言などをまと めたファイルである.
次に示すヘッダファイルは, 「ネームカードの構造体」,「ネームカードを管理する構造体」,それから, 「これら構造体のメモリ確保の関数(nc_folder_create)」, 「名前を登録する関数(nc_folder_entry_name)」, 「ネームカードの管理状態を表示する関数(nc_folder_dump)」 をまとめている.
/* * name_card_folder.h */ #ifndef __NAME_CARD_FOLDER_H__ #define __NAME_CARD_FOLDER_H__ typedef struct { char *name; // 名前を格納する場所 } NameCard; typedef struct { NameCard *cards; int max_name_length; // NameCard の name 変数で確保したサイズ int max_cards; // NameCard の確保したサイズ int num; // NameCard の使用可能なインデックス番号 } NCFolder; // ネームカードを管理するフォルダー // 第1引数は,ネームカードの枚数の上限. // 第2引数は,ネームカードの名前の文字列の上限. // 返り値は,フォルダー NCFolder *nc_folder_create( int, int ); // フォルダーのネームカードに名前を書き込みをする // 第1引数は,ネームカードフォルダー // 第2引数は,書き込む「名前」 // 返り値は,ない void nc_folder_entry_name( NCFolder *, char * ); // フォルダーの中身を標準エラー出力に表示する // 第1引数は,ネームカードフォルダー void nc_folder_dump( NCFolder * ); #endif |
ヘッダファイルに対応したソースファイルを作る.
/* * name_card_folder.c */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "name_card_folder.h" /* ネームカードフォルダを作る */ NCFolder *nc_folder_create( int num, int len ){ NCFolder *ans; int i; ans = ? NCFolder のメモリ確保 ? ans が NULL ならばエラー終了.サブルーチンの中から終了するには,exit(数); を実行すればよい. ans->cards = ? NameCard を num の数だけ確保 ? もし ans->cards が NULL ならばエラー終了 ans->max_name_length = len; ans->max_cards = num; ans->num = 0; for( i = 0; i < ????; i += 1 ){ ans->? cards の i 番目の name(文字列)のメモリ領域を確保.サイズは len ? 確保に失敗したときの処理をする(エラー終了) } ? ネームカードフォルダーのポインタを返す. } /* ネームカードフォルダに新しい名前 name を追加登録する */ void nc_folder_entry_name( NCFolder *ncf, char *name ){ ? もし,フォルダの num が,max_cards 以上ならば,エラー終了 ? もし,name が max_name_length - 1 以上ならば,エラー終了 ? フォルダの num 番目のカードに,name を登録(文字列コピー) ? フォルダの num を 1 つ増やす } /* ネームカードフォルダーの内容を表示(ダンプ)する */ void nc_folder_dump( NCFolder *ncf ){ int i; for( i = 0; i < ncf -> max_cards; i += 1 ){ fprintf( stderr, "%d: %s\n", i, ncf->cards[i].name ); } } |
上記のヘッダファイルとソースファイルから,ネームカードを管理するための ライブラリが作成できる. ライブラリだけでは,プログラムは動かない. ここでは,ライブラリを使用するメインファイルを作る.
/* list0301.c */ #include <stdio.h> #include ? #include "name_card_folder.h" #define MAX_CARDS 10 #define MAX_NAME_LEN 20 int main(){ NCFolder *ncf; int i; char buff[BUFSIZ]; ncf = nc_folder_create( MAX_CARDS, MAX_NAME_LEN ); for( i = 0; i < MAX_CARDS; i += 1 ){ if( fgets( buff, BUFSIZ, stdin ) == NULL ) break; ? 行末が \n ならば削除する ?(文字列の長さは,次の関数内で処理するのでここでは気にしなくてよい) nc_folder_entry_name( ncf, buff ); } nc_folder_dump( ncf ); return 0; } |
ライブラリのソースファイルとメインファイルは別々にコンパイルをした後で,統合する. 次の手順でコンパイルをすればよい.
$ gcc -Wall -c name_card_folder.c $ gcc -Wall -o list0301 list0301.c name_card_folder.o
しかし,いつも手で上記の手順を入力することは面倒くさい. そこで,Makefile にコンパイルの手順を定義する.Makefile は次のように書く.
CC = gcc CFLAGS = -Wall name_card_folder.o: name_card_folder.c name_card_folder.h $(CC) $(CFLAGS) -c name_card_folder.c list0301: list0301.c name_card_folder.o name_card_folder.h $(CC) $(CFLAGS) -o list0301 list0301.c name_card_folder.o clean: $(RM) *.o core.* |
Makefile を使ったコンパイルの実行は次のように,コマンドラインで操 作すればよい.
$ make list0301
ちなみに,不要なファイルを削除するには,以下を実行すればよい.
$ make clean