プログラミングU 第13回

線形リスト 3


ファイルから読むときにリストを作るようにする

表に読み込みながらリストを作る
       type
         String10 = string[10];
         TSoeji   = 0..9;
         TKojin   = record
                      Namae : String10;
                      Ten   : Integer;
                      Next  : TSoeji;
                    end;
         THyou    = array [TSoeji] of TKojin;

       var
         Ninzuu   : TSoeji;
         First    : TSoeji;
         Hyou     : THyou;

       procedure FileKaraYomu;

         procedure ListNiTsuika(N : TSoeji; var P : TSoeji);
           begin
             if (P > 0) and (Hyou[P].Ten > Hyou[N].Ten)
               then ListNiTsuika(N,Hyou[P].Next)            // 再帰呼び出し
               else begin
                      Hyou[N].Next := P;
                      P := N;
                    end;
           end; {ListNiTsuika}

         var
           InF : Text;
           K   : TSoeji;
         begin
           Assign(InF,'Seiseki.txt');
           Reset(InF);
           First := 0;
           K := 0;
           repeat
             Inc(K);
             ReadLn(InF, Hyou[K].Namae, Hyou[K].Ten);
             ListNiTsuika(K,First);
           until EoF(InF);
           Close(InF);
           Ninzuu := K;
         end; {FileKaraYomu}
       

表に読み込む方式は,あらかじめ Hyou を用意しないといけない. 用意した Hyou が小さいとすべてのデータを読み込むことができない. 大きな Hyou を用意するとデータが少ないときもったいない.
あらかじめ用意した表に読み込むことをやめて, 必要になったときに必要なだけの領域を確保して(動的割付という)読み込むようにする.
       type
         String10 = string[10];
         PKojin   = ^TKojin;
         TKojin   = record
                      Namae : String10;
                      Ten   : Integer;
                      Next  : PKojin;
                    end;
          // THyou は使わない

       var
         Ninzuu   : Integer;
         First    : PKojin;
         // Hyou は使わない

       procedure FileKaraYomu;

         procedure ListNiTsuika(N : PKojin; var P : PKojin);
           begin
             if (P <> Nil) and (P^.Ten > N^.Ten)
               then ListNiTsuika(N,P^.Next)
               else begin
                      N^.Next := P;
                      P := N;
                    end;
           end; {ListNiTsuika}

         var
           InF : Text;
           K   : PKojin;
         begin
           Assign(InF,'Seiseki.txt');
           Reset(InF);
           First := Nil;
           K := Nil;
           repeat
             New(K);
             ReadLn(InF, K^.Namae, K^.Ten);
             ListNiTsuika(K,First);
           until EoF(InF);
           Close(InF);
           // このままでは Ninzuu はわからない
         end; {FileKaraYomu}
       
たびたび出てくる ^ は → (データを指し示す矢印)の気持ちである. 半角文字には矢印がないので↑に似ている(?) ^ を使っている.
PKojin = ^TKojin
個人データ TKojin を指すポインタの型である.
Hyou を使う場合は添え字 TSoeji であったが, 動的割付の場合はシステムが割り付けた記憶領域の番地である.
私たちはその番地がどこかは知る必要がない.場所さえあればどこでもよい.
New(K)
表の場合 Inc(K) と書いてあった.
すなわち,表の中の新しいデータを読み込む位置を決めていた箇所である.
New(K) はシステムが記憶領域を確保して,その番地を K に入れる命令である.
K^ (P^,N^)
表のとき Hyou[K] (Hyou[P],Hyou[N])と書いてあった.
すなわち K番目の個人データのレコードである.
K^ は K→ の意味で,K が指しているレコードである.
Nil
表では 0 と書いてあったもので, データを指していないこと(空ポインタ,リストの終わり)を意味する定数である.

デモを見る