Practice 4: Profile 構造体の定義 他¶
構造体は,C言語において複雑なデータ構造を扱うために不可欠です.しかし,構造体は,配列やポインタよりも遅れて詳細が規格化されたため,これまでの解説があてはまらない部分があり,注意が必要です.
解説「構造体について」と解答例(前半・後半)を用意しました.まず,解説を読んで考えみましょう.解答例を見るのは,慎重に.
また,今回の内容からは,名簿管理プログラムの作成を強く意識していきます.実装を考える際には,演習課題説明資料PDFの付録Aを読み返しながら,考えるようにしてください.
プロジェクトの開始(3): レポートBの準備と作成¶
Practice 2 のプロジェクトの開始(2): レポートAの準備と作成で実施したことを思い出して,レポートBの執筆準備をしておきましょう.
レポートBの詳細は演習課題説明資料PDF 4章で説明しています.
練習4-1 プログラムをどこから作り始めるか (2/2)¶
前回の解説で示した「名簿管理プログラムの流れ ver.1」について,以下の処理をもう一段階詳細化せよ.
5つの文字列を項目毎に構造体や配列に保存;
練習4-2 struct profile の定義¶
下表に示すデータを格納するために構造体struct profileとstruct dateを定義せよ.
ID |
氏名 |
誕生日 |
住所 |
備考データ |
|---|---|---|---|---|
32 bit整数 |
70 bytes |
struct date |
70 bytes |
任意長 |
表中の 70 bytes は, 文字列が'\0'を含めて70バイトのchar配列に格納可能であることを意味する.
例えば,struct dateは,以下の通り.
struct date {
int y; // year
int m; // month
int d; // day of month
};
練習4-3 profile 構造体の配列の宣言¶
名簿データを保持するため,以下の2つの変数を,グローバル変数(広域変数)として宣言せよ.
この時,演習課題説明資料PDFに記載された仕様に基づき,少なくとも10,000件のデータが保存できるようにすること.
struct profile型の配列で,名前はprofile_data_store備考:名簿データそのものを格納するための変数
型定義は,練習4-2で実施済み.ここでは,定義した型を利用して,変数を宣言する
int型で,名前はprofile_data_nitems備考:配列
profile_data_storeに入っている有効な名簿データの個数を数えるための変数
注釈
本講義では,グローバル変数の定義にexternは,常に不要と考えて構わない.つまり,関数外で変数を定義しておけば,各関数内でexternを利用した宣言をする必要はない.
K&Rの「1.10節 外部変数と適用範囲(36ページ以降)」における,外部変数に該当する.ただし,本講義で作成するソースコードは,常に1ファイルとして進めているため,p.40の最終段落に書かれているように,externは利用しなくてもよい.
練習4-4 new_profile() 関数の実装¶
練習4-1や「名簿管理プログラムの流れ ver.1」を踏まえて,new_profile()関数を定義せよ.
new_profile()関数は,以下のparse_line()のように呼び出される関数である.
グローバル変数profile_data_storeとprofile_data_nitemsは,練習4-3で定義している.
1 2 3 4 5 6 7 8 | void parse_line(char *line)
{
if (line[0] == '%') {
exec_command(line[1], &line[3]); /* line[2] must be ' ' */
} else {
new_profile(&profile_data_store[profile_data_nitems++], line);
}
}
|
- ヒント:
まずは,6行目を読み解き,
new_profile()関数の呼び出しがどのように行われているか,精査しよう.例えば,printf("%d", 2 * 10);
と,
int n; n = 2 * 10; printf("%d", n);
は,同じ出力結果が得られる.各自で理解できる範囲まで分解してみよう.合わせて,教科書K&R 2.8節 (pp.57-59) も参照してほしい.
練習4-5 print_profile() 関数の作成とテスト¶
%Pコマンドでの利用を考慮して,構造体の中身を画面に表示するための関数print_profile()を作成せよ.
関数の出力は%Pコマンドに準拠すること.
関数の引数や戻り値は,各自で検討し,最も適切と思われる方法で実装すること.
また,print_profile()関数と,練習4-2~4-4の動作を確認するため,テスト用のmain()関数を作り,簡単な動作確認を実施せよ.
ヒント:
表示すべき構造体を特定するために,何らかの引数は必須である.しかし,特定する方法は一つとは限らない.
まずは,解説の最後に示したListing 13を用いて,
profile1構造体に対するprint_profile1()関数の試作をしてみるとよい.解説を振り返りながら,いくつかの実装方針を考えてみよう.すなわち,名簿管理プログラムの最終実装としては,各自の考えに基づく最善の実装を示し,その他は考察として説明すればよい.