問題
- control z (windows) control d (UNIX)が入力されるまで、整数型データを格納する。
19 30 41 (←ここまで入力。control zとENTER) 19 (先頭から、出力) 30 41

- 配列を使用しないで、整数データを格納する構造体を使う。次の構造体へのポインタも格納して、先頭からつないでいく。
- 1つずつのデータが構造体。次のデータへのポインタ(アドレス)をもつ
- append関数は、これまでのデータの最後に追加する。ptは先頭の構造体を指すポインタ
- リストを、構造体を使って実装する方法はいくつかある。
- 今回の方法は、先頭要素の扱いが、「あるごりずむ」の方法とは異なる。
- どちらにも慣れてほしい。
#include <stdio.h> #include <stdlib.h> /* 場合に応じて関数を切り替えるときに、置き換え(define)を使う */ #define MALLOC malloc /* #define MALLOC GC_MALLOC */ #define FREE free /* 整数と、次の要素を示すポインタからなる構造体を定義。次々つないでいく */ typedef struct _list { int n; struct _list *next; } list; /* list型データを1つ作成する。アドレスが戻り値 */ list *newList (void) { list *tmppt; tmppt = (list *)MALLOC(sizeof(list)); tmppt->next = NULL; /* nextはNULLで初期化 nは初期化せず */ return tmppt; } /* 最後に追加 : NULLだったら (最後の要素を見つけたら) セルを一つ 作成して 付け替える。append関数は、先頭のアドレスを返す */ list *append (list *pt, int i) { list *newcell; if (pt == NULL) { /* セルを1つ作っているだけ。ptとはつないでいないことに注意 */ newcell = newList(); newcell->n = i; return newcell; /* セルのアドレスをリターン。では、どこでつながるのか */ } else { /* 再帰条件 */ pt -> next = append(pt->next, i); /* ここ、何を言っているのか、読もう */ return pt; /* 自分をリターン。つまり、リストの先頭 */ } } void printlist (list *pt) { while (pt != NULL) { printf("%3d \n", pt -> n); pt = pt -> next; } } /* p.96より */ void FreeData(list *pt) { if (pt != NULL) { FreeData(pt->next); FREE (pt); } } /* Control zまで、繰り返して、append */ int main (void) { int i; list *pt; pt = NULL; /* 空リスト準備完了 */ while (scanf("%d", &i) != EOF) { pt = append(pt, i); } printlist(pt); /* 先頭からプリント */ FreeData(pt); /* 先頭から、1つずつfree */ return (0); }