|
15番会議室「FAQ編纂委員会」に寄せられた「よくある質問の答え」
[Q]
一次元配列を動的に確保して使う方法はわかりましたが,2次元の配列
で同様にやるにはどうしたらよいですか?
[A]
一つの解決法は,一次元の配列をたくさん確保しながら,それへの
ポインタをひとつづつ拾ってこれを配列に入れるやり方ですが,
それぞれの一次元配列をばらばらととってくるので,連続した大きな
領域にならない可能性があるのがたまにきずです.
そこで,変数領域は一気にがばっととってきて,それを一次元の
配列がずらっとならんでいると見立てて,ポインタを順番にあてがう
やりかたにしてみました.
[例]
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, Mask, ComCtrls, Grids;
type
TForm1 = class(TForm)
Button1: TButton;
StringGrid1: TStringGrid;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
// 二次元配列を動的に確保して使う一般的な方法の例
// 行列は「一次元配列へのポインタの配列」として扱うが
// メモリの確保は一括してまとめて行う
// 添え字は0からに固定
{
ベクトルの要素へのアクセス
pV:N個の要素を持つ配列へのポインタ
^ pV^[0]
| pV^[1]
N
|
v pV^[N-1]
行列の要素へのアクセス
pM:NJ個の要素を持つ配列へのポインタの配列へのポインタ
<------------ NI ------------->
^ pM^[0][0] pM^[NI-1][0]
| pM^[0][1]
NJ
|
v pM^[0][NJ-1] pM^[NI-1][NJ-1]
}
const
Ndim = 1500; {Maximam Vector size that you can change}
type
TVector = array[0..Ndim-1] of double;
PVector = ^TVector;
PMatrix = array[0..Ndim-1] of PVector;
implementation
{$R *.DFM}
procedure Keisan(NI, NJ: integer; Grid: TStringGrid);
var
I,J : Integer;
pM : ^PMatrix;
pV1, pV2 : PVector;
tempP : Pointer;
begin
// メモリの確保
// ベクトル
pV1 := AllocMem(NI * SizeOf(Double)); // 数値が入る領域1
pV2 := AllocMem(NJ * SizeOf(Double)); // 数値が入る領域2
// 行列
pM := AllocMem(NI * SizeOf(Pointer)); // ヘ゛クトルへのホ゜インタの配列
tempP := AllocMem(NI * NJ * sizeof(Double));// 数値が入る領域3
for I := 0 to NI-1 do begin
pM^[I] := Pointer(Longint(tempP) + I * NJ * SizeOf(Double));
end;
try
// 値の取り込み例
for I := 0 to NI-1 do begin // Gridの1列目を取り込み
pV1^[I] := StrToFloat(Grid.Cells[1,I+1]);
end;
for J := 0 to NJ-1 do begin // Gridの2列目を取り込み
pV2^[J] := StrToFloat(Grid.Cells[2,J+1]);
end;
// 実際の計算(かけ算の例)
for I := 0 to NI-1 do begin
for J := 0 to NJ-1 do begin
pM^[I][J] := pV1^[I] * pV2^[J]; // 要素へのアクセスの記述例
end;
end;
// 結果の表示
for I := 0 to NI-1 do begin
for J := 0 to NJ-1 do begin
Grid.Cells[I+1,J+1] := FloatToStr(pM^[I][J]);
end;
end;
finally
// 使ったメモリの廃棄
FreeMem(pM^[0], NI * NJ * SizeOf(Double));
FreeMem(pM, NI * SizeOf(Double));
FreeMem(pV1, NI * SizeOf(Double));
FreeMem(pV2, NJ * SizeOf(Double));
end;
end;
// Gridにはイカのように入力しておく
{
--- --- ---
--- 1 1
--- 2 2
--- --- 3
--- --- 4
--- --- 5
}
procedure TForm1.Button1Click(Sender: TObject);
begin
Keisan( 2, 5 ,StringGrid1); // 要素数が数値として渡される
end;
end.
ここにあるドキュメントは NIFTY SERVEの Delphi Users' Forum FDELPHIに寄せられる質問の中から、よくある質問への回答を FDELPHIのメンバーがまとめたものです。 したがって、これらの回答はボーランド株式会社がサポートする公式のものではなく、掲示されている内容についての問い合わせは受けられない場合があります。
Copyright 1996-1998 Delphi Users' ForumFAQ編纂委員会
|