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
| Old | New | Line | |
|---|---|---|---|
| 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).* |
