可変長の配列を、定義する、またはサイズ変更します。
構文:
動的配列のサイズ変更:
Redim [ Preserve ] symbolname([subscript [, ...]]) [, ...]
または:
Redim [ Preserve ] [ ( ] expression [ ) ] ([subscript [, ...]]) [, ...]
パラメタ:
Shared
モジュール全体で、配列への共有(ファイル範囲)アクセスを指定します。
Preserve
既存の配列に
Preserve を使うと、サイズ変更しても、配列の内容は、保存されます。
注意:
Preserve は、場合によって、その元の添字で、データを保存しなことがあります。以下を見て下さい。
symbolname
新規か、もしくは既存の、配列 ID。
expression または
(expression)
既存の配列を参照する式。 これは、ユーザー定義型のメンバーである配列のサイズを変更するために使えます。
場合によっては、式の前後に括弧を指定する必要があります(特に、配列式自体に括弧が含まれている場合)。
- 下の例を参照してください。
subscript: [
lowerbound To ]
upperbound
配列の次元に対する、下限と上限の範囲。(添え字)
指定しないと、下限はデフォルトでゼロ (
0) になります。または、
Base で指定したデフォルトになります。
datatype
配列に含まれる要素の型。
記述:
Redim は、新しい可変長配列を定義したり、既存の可変長配列を、元の次元数を保持した状態で、サイズ変更するために、使います。
Redim は、常に可変長配列を生成します。
Dim とは異なり、定数の添字を使って可変長配列を定義します。
新しい可変長の配列を定義するとき、要素数は、デフォルトで生成されます。
Integer や
Double のような簡単なデータ型に関しては、要素は、ゼロ (
0) に初期化されます。
デフォルト構築子を持つユーザ定義型の場合は、これが呼び出されます。
ユーザー定義型で
Redim を使うと、可変長の配列を作成すると同時に、定数の添え字で事前にサイズ設定できます。
注意:
- Redim Preserve は、すべての場合で予想どうりに機能するとは限りません:
-
Preserve の現在の動作は、元のデータを、メモリ内で連続した状態に保ち、メモリのサイズを拡大または切り捨てるだけです。
(サイズ変更ができない場合は、元のデータブロック全体が、最初に別のメモリ位置にシフトされます。)
-
1次元配列の振る舞いは、上限が変更されたときにのみ、明確に定義されます。
下限が変更されると、現在の結果は、データが新しい下限から開始するようにシフトされます。
-
多次元の配列は、最初の次元の上限だけを安全に増やすことができます。 最初の次元を縮小すると、既存の配置されたデータが失われる可能性があります。
下位の次元のサイズを変更すると、予測できない結果になります。
(多次元配列は行優先順で格納されています。連続しているのは、最後のインデックスが異なる値だけだからです。)
- Redim は、固定長の配列(つまり、Dim で作成した一定の境界を持つ配列)では使えません:
渡辺注:Dim() で作った配列には使えます。
- これは、UDT(ユーザー定義 Type)に含まれる固定長の配列も同じです。
- これには、手続きでパラメータとして渡される固定長配列も含まれます。
:FreeBASIC は、コンパイル時に通るかもしれませんが、実行時にエラーになります。
- メンバー手続きの中で、オブジェクト・クラスのインスタンスを含む配列に Redim を使うことはできません。おそらく恐ろしいクラッシュを引き起こします:
- 配列データが Redim によってメモリ内で移動すると、渡された This 参照は、中ぶらりんの[解放済みのメモリー領域を指している]ポインタと同じように、一貫性がなくなります。
-
この場合、このメンバー手続きから非静的メンバー フィールドへの後続のアクセスはすべてエラーになります。
ただし、このメンバー手続きの本体で Redim を実行した直後に、渡された This 参照が (@This = @array(...) を使って) 再調整された場合は除きます。
-
Redim を複雑な配列式で使う場合(特に、配列式自体に括弧が含まれている場合)、解析のあいまいさを解決するために、配列式を括弧で囲む必要があります。
例:
'' 可変長の配列を、5つの要素で定義します
''
ReDim array(0 To 4) As Integer
For index As Integer = LBound(array) To UBound(array)
array(index) = index
Next
'' 可変長の配列を、10の要素にサイズ変更します
'' (下限は、変わっていません。)
ReDim Preserve array(0 To 9)
Print "index", "value"
For index As Integer = LBound(array) To UBound(array)
Print index, array(index)
Next
Sleep
このプログラムを実行すると、下のように出力されるでしょう:
index value
0 0
1 1
2 2
3 3
4 4
5 0
6 0
7 0
8 0
9 0
'' 可変長の配列を定義します
Dim array() As Integer
'' 配列を、3*4 の要素に再定義します
ReDim array(1 To 3, 1 To 4)
Dim As Integer n = 1, i, j
Print "3 * 4:"
Print
For i = LBound(array, 1) To UBound(array, 1)
For j = LBound(array, 2) To UBound(array, 2)
array(i, j) = n
Print Using "## "; array(i, j);
n += 1
Next
Print
Next
Print
'' 配列の内容を保持したままで、配列の要素を 4*4 に再定義します
'' (最初の次元の、上限だけを変えます)
ReDim Preserve array(1 To 4, 1 To 4)
Print "4 * 4:"
Print
For i = LBound(array, 1) To UBound(array, 1)
For j = LBound(array, 2) To UBound(array, 2)
Print Using "## "; array(i, j);
Next
Print
Next
Print
'' 配列を、内容を保存しますが、上限部分を切り取って、2*4 の要素に再定義します。
'' (最初の次元の上限だけを変えます)
ReDim Preserve array(1 To 2, 1 To 4)
Print "2 * 4:"
Print
For i = LBound(array, 1) To UBound(array, 1)
For j = LBound(array, 2) To UBound(array, 2)
Print Using "## "; array(i, j);
Next
Print
Next
Print
Sleep
このプログラムを実行すると、下のように出力されるでしょう:
3 * 4:
1 2 3 4
5 6 7 8
9 10 11 12
4 * 4:
1 2 3 4
5 6 7 8
9 10 11 12
0 0 0 0
2 * 4:
1 2 3 4
5 6 7 8
'' 可変長配列を UDT フィールドとして定義する
Type UDT
Dim As Integer array(Any)
End Type
Dim As UDT u(0 To 3)
'' 複雑な配列式でRedimを使用するには、
'' (特に配列式自体に括弧が含まれている場合),
'' 構文解析のあいまいさを解決するために、
'' 配列式を括弧で囲む必要があります:
'' Redim u(0).array(0 To 9)
'' induces error 4: Duplicated definition, u in 'Redim u(0).array(0 To 9)'
ReDim (u(0).array)(0 To 9)
QBからの違い:
-
Preserve は、Visual Basic にはありましたが、QBASIC には、有りませんでした。
- FreeBASIC の多次元配列は、列優先ではなく行優先で格納されます。
参照: