リスト処理とは、データの集まりを処理するための多くの手法に付けられた名前です。 配列、構造体、および共用体もデータの集まりを処理するために使われますが、リ スト処理手法は、プログラムの実行中にデータの集まりを無限に再配列したり、 広げたりすることができるという点で、融通性があります。 ここでは、これらの手法については説明しませんが、基底付き変数とロケーター変数がこの種の処理の基礎としてどのような働きをするかを説明します。
リスト処理では、多数の基底付き変数 (それぞれが 1 つ以上の世代を持っている) を 1 つのリスト内に入れることができます。 このリスト内のメンバーは、ほかのメンバーまたはほかのリストの位置を指し 示す 1 つ以上のポインターをメンバー内に持つことによって、相互に関連してい ます。 基底付き変数を割り振るときには、主記憶域内のどこにその変数を割り振るか を指定することはできません (ただし、どの区域内に割り振りたいかを指定する ことはできます)。 実際には、チェーニングしている項目は主記憶域全体にわたって分散していることもあります。しかし、 それぞれのポインターをアクセスすれば、次のメンバーが見つかります。 リスト内のメンバーは、通常は、ポインター変数を含む構造体または共用体です。 次の例では、構造体のリストが作成されます。
dcl 1 STR based(H),
2 P pointer,
2 data,
T pointer;
allocate STR;
T=H;
do loop;
allocate STR set(T->P);
T=T->P;
T->P=null;
·
·
·
end;
これらの構造体は、STR のいくつかの世代であり、各世代の中のポイ ンター変数 P によって相互にリンクされます。 リストを作成している間、ポインター変数 T は前の世代を識別します。 最初の ALLOCATE ステートメントは、世代を示すようポインター H をセットします。 つまり、ポインター H はリストの開始点 (リストの先頭) を示します。 2 番目の ALLOCATE ステートメントは、 前の世代の中にあるポインター P が この新しい世代の位置を示すよう、 ポインター P をセットします。 代入ステートメント T=T->P; は ポインター T を更新し、 新規の世代の位置を識別できるようにします。 代入ステートメント T->P=NULL; は、 リストの最後の肯定のディレクティブを指定して、 NULL の最後の世代内にポインターを設定します。
図 19 は、一方向のチェーンを図解したものです。
各世代の中にある P の値が、各世代ごとに別々のポインター変数に 割り当てられているのでない限り、STR の各世代は、リストが作成 された際の順序でしかアクセスできません。 上の例の場合、下記のステートメントを使用すれば、各世代を順に アクセスすることができます。
do T=H
repeat(T->P)
while (T¬=null);
·
·
·
T->data;
·
·
·
end;
先に挙げたいくつかの例は、一方向のリストを作成する簡単なリスト処理 手法です。 別のポインター変数をこの構造体内または共用体内に追加すれば、さらに複雑なリストを作成することができます。 別のポインター変数を追加したとすれば、それで前の世代を指すことができます。 それにより、リストは双方向となります。リストの任意の項目から直前の項目と次の項目に、該当するポインター値を使用してアクセスすることができます。 最新のポインター値を NULL の値にセットする代わりに、リスト内の最初の項目を指すようにセットすれば、リング状リスト (循環リスト) を作成することができます。
リストは、1 つの基底付き変数の世代だけで構成する必要はありません。 複数のポインター値を適切にセットすれば、複数の異なる基底付き構造体または 共用体の世代を 1 つのリスト内に入れることができます。 それらのポインターの値を操作することによって、リストに項目を追加したり、リストから項目を削除したりすることができます。 ポインターを操作することによってリストを再構成することができ、その結果リスト内のデータの処理が簡素化されます。