Sign in Join
Wiki copytemporary

Dynamic array/ja: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Dynamic array/ja

OldNewLine
1+動的配列は、 FreePascal ( と Delphi) のとても便利な機能です。それは、 [[Array/ja|配列]] 型ととてもよく似ていますが、プログラムの実行時以前に要素数を決める必要がないことから、プログラマーにより高い柔軟性をもたらします。
2+
3+宣言部は、[[Array/ja|配列]] 型においても大変シンプルな記述となっています。:
4+
5+``` pascal
6+var
7+ ...
8+ MyVariable : array of type;
9+ ...
10+```
11+
12+要素の数は、 SetLength 宣言を挿入することで、プログラムの実行中に、いつでも必要に応じて設定することができます。:
13+
14+``` pascal
15+begin
16+ ...
17+ SetLength(MyVariable, ItsNewLength);
18+ ...
19+end
20+```
21+
22+**SetLength** 宣言は、配列を拡大したり切り詰めたりするために、プログラム中で何回でも、どの位置でも宣言できますが、初めて配列を用いる前に、少なくとも1回は宣言する必要があります。
23+
24+個々の要素へのアクセスは、以下のようにして行います。:
25+
26+``` pascal
27+...
28+SetLength(MyVariable,19);
29+...
30+MyVariable[18] := 123;
31+...
32+MyOtherVariable := MyVariable[0];
33+...
34+WriteLn('MyVariable has ', Length(MyVariable), ' elements'); {should be 19}
35+...
36+WriteLn('Its range is ', Low(MyVariable), ' to ', High(MyVariable)); {should be 0 to 18}
37+...
38+```
39+
40+動的配列のインデックスは、0「ゼロ」が下限となります。すなわち、範囲は 0 から (Length-1)までとなります。 これを、1「イチ」 がインデックスの下限になるようには、できません。
41+
42+実際には、動的配列は自動的に再参照(automatic dereferencing)を行うポインタです。 それらは、自動的に **nil** に初期化されます。 これは、 変数 **MyVariable** を **fillchar**, **sizeof**,などの低レベルのルーチンを通して扱うとき、ポインタ変数として翻訳されることを意味します。 しかし、その要素をインデックス化する際( in **MyVariable\[2\]** のように)、または、その配列を入出力とするルーチンに渡されるとき、それは自動的に **MyVariable^** に展開されます。
43+
44+メモリー管理の点からは、動的配列は単純なポインタです。 **SetLength** がアロケートを行い、また、必要に応じてヒープ上のメモリを解放します。 ファンクションやプロシージャとして扱うときは、ポインタのみがスタックに加えられます。 プロシージャから出るときは、動的配列の値は取り除かれ、メモリーはまた利用できるようになります。 実際には、メモリー管理プロシージャは実行プログラムに挿入されており、その結果として、全体的にプログラマーにとって見通しが良くなっています。
45+
46+動的配列に **nil** をアサインすることは、自動的にポインタが示す位置のメモリーを開放します。 それは、 **SetLength(MyVariable, 0)** と一致します。 もしポインタ値がなんらかの理由で妥当(valid)ではなくなったときに(すなわち、以前のプログラムが実行した際に保存された位置に、ディスクから読み込まれたなど)、副作用が起こり値が変化するかもしれません。 このような invalid なポインタを初期化するためには、 **FillChar(MyVariable,sizeof(MyVariable), \#0)** を使う必要があります。
47+
48+動的配列の要素に書き込むことは、配列の新たなインスタンスを **作りません** が(Ansistrings にある no copy-on-write のように) 、そのような配列に **SetLength** を使うことはコピーを **作ります!** なので、もし2つの動的配列が同じ配列をポイントしていたなら(一方はほかの配列にアサインされています)、それらの配列は **SetLength** を一方(または両方)に用いた後とはふるまいが異なります。 SetLength() 呼び出しのあとでは、2つの配列は各要素がお互いに独立した配列となります。
49+
50+## 関連情報
51+
52+- [Free Pascal Reference guide: Dynamic arrays](http://www.freepascal.org/docs-html/current/ref/refsu15.html#x39-520003.3.1)
53+- [[Example: Multidimensional dynamic array/ja]]
54+- [[Array/ja]]
55+
56+---
57+*From the Free Pascal wiki, page "Dynamic array/ja", as it stood on 2020-02-14 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history