|
数値を配列として使いたい - - 動的配列の場合 |
|
データを読み込んで計算する場合など、毎回データ数が異なる個数の数値を読み込む ことが多々あります。そんなときは動的配列やリストを使って処理をします。 ここでは動的配列の例を示します。 動的配列では、数値を代入する前にSetLength手続きで 配列の長さを欲しいデータ数以上にします。 SetLength(動的配列,長さ) SetLength手続きでは、長さは0〜255の数字です。そのため、動的配列は 最大で255のデータしか保持できないように思われますが、次のようにarray of 型をいれこにすることで255以上のデータを保持できます。 var X_Value : array of array of Integer; ※実は255を越えて要素を持つことようですが、
その限界値は不明です。やってみたら480個程度までは配列になりましたが、その後
の配列に正しいデータが入っていなかった記憶があります。
上記は整数型の動的配列の変数宣言です。この配列では最大 255×255=65025個のデータを配列に持つことができます。次のコードで確かめられる と思います。このコードは、フォーム上にLabel1とButton1が配置された簡単なものです。 Button1を押すと1〜65025までの和をLabel1に表示します。
実行結果(左:ボタンを押す前、右:押した後)
簡単な説明 上のコードでは、値を配列に入れる直前※1にSetLength手続きで 配列のメモリを確保しています。今回のコードでは配列の個数が65025と分かっていますが、 実際に読み込むデータ数が分からない場合にはこのように書くことになると思います。 arrayをいれこにした場合、添え字は次のようになります。 Value[ i , j ]
SetLengthはまず i の大きさに関して行い(A行)、i の大きさが決まったら 各Value[ i ]に対してSetLengthを行って(B行)います。SetLengthでは配列の個数を指定しますが、 配列の添え字は0から始まるためSetLengthでは+1しています。 SetLengthは新たにメモリ領域を確保する手続きなので、 メモリ不足の場合はエラー(EOutOfMemory)を引き起こします。それを感知できるようにSetLength をtry 〜 exceptで挟んでいます。try文中でEOutOfMemoryエラーが発生した場合、 on E:EOutOfMemory 〜 end;部が実行されます。このコードでは、ユーザにメモリ不足を 通知(ShowMessage()部)してButton1Click手続きを終了するようになっています。 動的配列Valueの各要素Value[ i , j ]にアクセスするには、 上述のように2つの変数 i , j を使いたくなりますが、i の商と余りを求める算術演算子 div、modを使うと j は不要になります※2。ちなみに、array of array of array of 型の 場合は、次のようになります※3。 SetLength部分
SeLength(Value,(i div 65025) + 1);
SetLength(Value[(i div 65025)],((i mod 65025) div 255) +1);
SetLength(Value[(i div 65025),((i mod 65025) div 255)],((i mod 65025) mod 255)+1); 配列の各要素
Value[(i div 65025),((i mod 65025) div 255),((i mod 65025) mod 255)]]
※1 このコードでは、 i が+1されるごとにSetLengthが呼び出される ため、先にデータ数を調べてwhile文の前でSetLegnthしてしまう方が早くなります。 ※2 変数を1つ減らすことができますが、足し算、引き算に比べて わり算はかなり計算速度を遅くします。そのため、divやmodを使うより j 、k などを導入 した方が高速になると思われます。もちろん、+1ごとに if (i mod 255) = 0 then とやってしまって はダメですが。。。 ※3 足し算を65536以上まで行うと、Integerの最大値 (2147483647、DelphiではMaxIntという定数)を越えてしまい、正しい結果を返しません。 |