†Sibylのお部屋†
作成開始日 2022.03.30
最終更新日 2022.04.12
以下、Sibylでは動的配列が使用できない事を前提としているが、本当のところは良く判らない。確かに、Sibylでは「array[1..5] of Integer」のように配列の添字のレンジ指定が必須で、Delphiのように「array of Integer」式の動的な配列宣言はできない。しかし、実際にはレンジ指定外の添字も使用可能なようだ。例えば、「x: array[1..5] of Integer」と宣言した場合でも、「x[8]:=…」行のコンパイルは通るし、機能も正常。実は隠し動的配列?う〜む、使える…のか?
Delphiでは動的配列が使用できるようだが、Sibyl/WDSibylでは使用できない。しかし、「TList型」は実質的にポインタの動的配列型なので、これをベースにすれば任意型の動的配列と同等の機能を実現できる。なお、「TStrings型」はこれまた実質的に動的な文字列型配列なので、文字列だけでよければ、こちらを使う方法もある(或は必要な情報をすべて文字列化するとかね)。以下では、例として「TList型」を用いて整数列(Integer型)の動的配列を作成する
Type TpInt=^Integer; //整数のポインタ型 Var n : Intger; pN : TpInt; //整数型のポインタ myList : TList; //作成する動的配列 Begin myList:=TList.Create; //リストの生成、myList.Createでも可 myList.Clear; //一応、明示的に初期化しておく ///// 文字列の代入:実際はループで処理することが多いだろう //1番目の要素[0]の追加 new(pN); //新しい整数型ポインタを作成 pN^:=123; //ポインタの中身に値を代入 myList.Add(pN); //作成したポインタをリストに追加 //以下、同様に任意個数だけ要素を追加可能 new(pN); pN^:=999; myList.Add(pN); //2番目の要素[1]の追加 new(pN); pN^:=0 ; myList.Add(pN); //3番目の要素[2]の追加 new(pN); pN^:=52 ; myList.Add(pN); //4番目の要素[3]の追加 ///// 値の参照:明示的に型キャスト(TpInt)しないと「^」参照ができない n:=TpInt(myList.Items[0])^; //「123」となる n:=TpInt(myList[2])^; //「0」となる、「Items」を省略した形 n:=Int(myList[2]); //この形式が通れば便利だが…どうだろう?ポイントは;
@「new」で新しいポインタを生成し、
A「^」で中身を設定し、
B「add」でリストに追加する=添字を付ける
と言う手順。追加する個数は任意で、一般的な配列のように予め上限を指定する必要はない。また、追加時にポインタを作成するため、必要以上のメモリも消費しない。ただし、上記のように、値の参照には型キャストが必要で、見栄えはよろしくない。
次に、もう少し実践的な例として、ファイル情報(ファイル名および各種属性)の一覧を取得して、動的配列に格納してみる。
Type TpSearchRec:=^TSearchRec; //リストに格納するデータのポインタ型 Var rec : TSearchRec; //ファイル情報を格納(構造体) pRec : TpSearchRec; //recのアドレスを格納 FileList: TList //ファイル情報の動的配列 fmask : String; Begin FileList:=TList.Create; FileList.Clear; fmask:='d:\mywork\*.*'; //「d:\mywork」のファイル一覧を取得する FindFirst(fmask, faDirectory, rec); //1項目の[.]は読み飛ばし While FindNext(rec)=0 Do //ループでファイル一覧を取得 Begin new(pRec); pRec^:=rec; //アドレスを渡せば全データにアクセス可能 FileList.Add(pRec); //アドレスをリストに追加 End; //参照の仕方はこんな感じ(stは文字列型、lはロング整数型) st:=TpSearchRec(FileList[5])^.Name; //6番目のファイルの名前を取得 st:=TSearchRec(FileList[5]).Name; //多分この形式も通る、つかこっちが基本? l :=TpSearchRec(FileList[8])^.Size; //9番目のファイルのサイズを取得