住所録プログラムの作成 (その1)
以下のような仕様の住所録を作成する。
学籍番号、氏名、ふりがな(ローマ字読み)、年齢、生年月日、住所等を構造体を用いて作成する。
プログラムの仕様
データは下のような構造体メンバーで構造体personalを作成する。
struct personal{ |
データの入力や表示、ファイル入出力を行うため、メニューを作成し、ユーザーが行いたいものを選択できるようにする。
メニューはprint_menu関数により表示し、scanfによりユーザーからの入力を得る。入力された番号をswitch文を用いて、それぞれの仕事を行う関数を呼び出すことにする。
print_menu関数は以下のようにする。
void print_menu() |
main関数はユーザーからの入力に合わせて、それぞれの仕事に対応した関数を呼び出すため、変数の宣言とswitch文からなる。
main() (以下、メニューの数だけ続く) |
データの入出力はそれぞれの関数を作成する。主に入力はscanf文、出力はprintf文からなる。
void get_data(struct
personal data[], int number) |
ファイルの入出力もデータの入出力と同様に実現できる。
ここでも、ファイル入出力用の関数を作成し、メニューで選択されたらその関数を呼び出すこととする。
ファイルのデータ書式は、先頭にデータ数、その後テキストで構造体のメンバーを順に羅列したものとする。
メニューによる呼び出しとファイル入出力関数は以下のように実現できる。
main() (省略) case(3): (省略) } |
メモリを確保する方法には次の二つの方法がある。
プログラム中で直接確保する方法。いままで用いてきた配列などは静的メモリである。
必要な時に必要なだけのメモリを確保、解放する方法。プログラム中で配列サイズが決定する場合などに有効である。
もし、住所録のデータを記憶するために配列を用いると宣言した配列の大きさ以上のデータを扱えなくなり、多くのデータが必要な時にはもう一度プログラムを書き換えてコンパイルし直さなくてはならない。それに対して動的にメモリを確保すれば、扱うデータ数が増えても必要なだけ記憶のためのメモリを確保できるので便利である。
メモリの動的な確保、解放を行うには次の関数を用いる。これらの関数の定義はstdlib.hにて定義されているので、これをインクルードする必要がる。
void *malloc(size_t size) void free(void *ptr) |
malloc関数はsizeで指定されたバイト数のメモリを確保し、確保したメモリへのポインタを返す。通常、代入したい変数の型へのキャストを行う。
free関数はポインタptrで示されたメモリ領域を解放する。
確保したいメモリの型(構造体)のバイト数はsiteof演算子を用いることによって知ることができる。例えば
printf("sizeof(double)= %d\n", sizeof(double)); printf("sizeof(FILE) = %d\n", sizeof(FILE)); |
とすれば、double、FILEそれぞれのバイト数が 8 バイト、 16 バイトであることが分かる。自分で作った構造体についても同様にして調べることができる。
動的に確保されたメモリはfree関数を用いて開放するか、プログラムが終了するまで確保されつづける。したがって、不要になったメモリは必ず解放すること。
以下はmalloc関数を用いてint型の100個の配列を獲得するサンプルである。ここで獲得された配列は以降通常の配列と同様に使用することができる。
#include<stdio.h> #include<stdlib.h> main() { int *array; /* メモリの獲得 */ array = (int*)malloc(sizeof(int)*100); free(array); } |
構造体の配列を動的に獲得する方法も同様にして実現できる。
#include<stdio.h> #include<stdlib.h> struct personal{ int no; char name[256]; char furigana[256]; int age; int year; int month; int day; char address[256]; }; main() { struct personal *array; /* メモリの獲得 */ array = (struct personal *)malloc(sizeof(struct personal) * 100); free(array); } |