多次元の入れ物の形式。
概要
配列は、複数の値や
要素を格納できる、特別な種類の
変数です。
配列はどんな型の要素でも格納することができます。その全ての要素は、同じ型を共有します。
たとえば、配列は、
Integer 要素も
Single 要素も格納できますが、両方を同時に格納することはできません。
これらの要素は、配列内の位置(
position)を意味する、
Integer 値を使ってアクセス― 読み書き ―されます。
配列の大きさ(
sizes)は、配列がその時々で格納する要素数と等しい長さになります。
固定長配列は、その生涯を通じて、一定の大きさを持っています。その一方、
可変長配列の大きさは、動的に変えることができます。
要素と位置
配列が保存する値は、その要素です。
配列の各要素は、対応する位置(配列の下限(
lower bound)から上限(
upper bound)の範囲の
Integer の値)を持っています。
これらの位置は、
演算子 () で、配列で個々の要素にアクセスするために用いられます。
演算子 () は、位置を取得して、その位置にある要素への参照を返します。
配列で有効な位置は、その下限から上限までの範囲です。
' すべてゼロ(0.0f)の値の、3つの要素の、配列を作成します。
Dim array(1 To 3) As Single
' 最初の要素に値を割り当てます。
array(1) = 1.2
' すべての要素の値(「1.2 0 0」)を出力します。
For position As Integer = 1 To 3
Print array(position)
Next
Sleep
大きさと範囲
配列の大きさは、配列がその時々で格納する要素の数と同じです。
配列の大きさをゼロ(0)にすることができます。これは、配列が、何の値も保存していないことを意味しています。つまり空です。
配列の大きさがゼロより大きいならば、その数の要素を格納しています。
配列の大きさは、その上限と下限の範囲の差より1大きい値、つまり
ubound(array) - lbound(array) + 1 になります。
下限と上限は、配列のサイズだけでなく、個々の要素の有効位置も決定します。
たとえば、下限が (0) 、上限が (4)の配列には、(5) つの要素が格納され、最初の要素は位置 0 に、最後の要素は位置 4 に格納されます。
これらの範囲は、配列の宣言時に指定しますが、配列によっては、配列のサイズを変更することもできます。
配列の下限と上限は、それぞれ
Lbound と
Ubound を使って取得できます。
配列を作ったり、大きさを変更するときに、下界を指定しないと、下限は、デフォルトで、ゼロ (0) になります。
' 4つの整数要素をもつ配列を宣言して、初期化します。
Dim array(3) As Integer = { 10, 20, 30, 40 }
' 要素の全ての値(「10 20 30 40」)を出力します。
For position As Integer = LBound(array) To UBound(array)
Print array(position) ;
Next
Sleep
固定長と、可変長
基本的に、
固定長 と、
可変長 の2種類の配列があります。2つの主な違いは、固定長配列は、下限・上限が、決して変わらないということです。つまり、固定長配列は、常に同じ数の要素を、同じ位置に格納します。
可変長の配列は、下限・上限を変えることができ、その結果、格納される要素の番号や、要素の場所が変わります。
固定長配列は、サイズを変更しないので、コンパイラーは、配列の
記憶域クラス に応じて、静的記憶装置の中か、あるいはプログラム・スタック上で、配列要素のためにメモリに、場所を確保するか、あるいは
allocate するかを選択します。
固定長配列を作るコストには、実行時の悪影響がないため、これは利点です。
固定長配列は、
Extern、
Static、
Dim を使って、宣言します。
少なくとも、上限を指定しなければなりません。そして、上限・下限は、コンパイル時に定数値(例えば数値直定数、
Const 変数、または
Enum 列挙)でなければなりません。
可変長配列は、大きさを変えることができるので、コンパイラは、実行時に、空いている貯蔵場で、配列要素に記憶域を割り当てるほうを選択します。
この利点は、動的に配列サイズを変更できることです。しかし、配列が作成、サイズ変更、破棄されるとき、実行時性能が変わってきます。
可変長配列は、
Extern、
Static、
Dim、
Redim を使って宣言します。
Extern、
Static または
Dim を使うとき、下限・上限は、指定しないままにすることができます。結果として、空の配列になります。あるいは、どちらか一方に、変更できる値(例えば
Integer の、変数または、
Function の結果)を指定します。
Redim を使うと、既存の可変長配列に異なる上限・下限を指定して、大きさを変えることができます。
' 5つの一つの要素を持つ固定長配列をつくります。
Const totalSingles = 5
Dim flarray(1 To totalSingles) As Single
' 整数値を入れるための、空の可変長配列をつくります。
Dim vlarray() As Integer
' 配列の大きさを、10の要素に変更します。
ReDim vlarray(1 To 10)
多次元配列
上で述べた配列は一次元でした。つまり、要素は、一つの位置を指定してアクセスされます。一次元の配列は、単純な「要素の行(row)」と考えることができます。
配列は、複数の次元をもつこともできます。配列の個々の要素は、2つ以上の位置を指定してアクセスされます。
二次元の配列は、個々の要素(格子や表のよう)を参照するために、2つの位置 --行(row)と列(column)-- を使います。
三次元配列は、個々の要素(立方体のよう)を参照するために、3つの位置 --行(row)と列(column)と深さ(depth)-- を使います。
四次元配列は、複数の三次元配列と考えることができます。
多次元配列は、一次元の配列と同様に宣言しますが、複数の下限と上限の範囲を指定する点が、異なっています。
多次元配列の要素の総数と合計サイズ(バイト単位)は、それぞれ
ArrayLen と
ArraySize をって直接取得できます。
' 多次元の配列を初期化している点に、注意してください。
Dim As Integer multidim(1 To 2,1 To 5) = {{0,0,0,0,0},{0,0,0,0,0}}
LBound と UBound の使い方
LBound /
UBound は、配列のサイズ情報を返します:
配列の次元(使える配列の添え字の数(種類))数と、各次元の配列の添え字の範囲(最小値と最大値)です。
最初のパラメータで配列名を指定し、2番目のパラメータで次元を指定します。
このサイズ情報は、固定長の配列(コンパイル時にサイズが固定されている)と可変長の配列(実行時にサイズを調整できる)の両方で利用できます。
- 用法:
result = (L|U)Bound( array [, dimension ] )
使うパラメータ:
array : 配列名、括弧を付けない
dimension : 範囲を取得する次元の数,配列にアクセスする際の添え字の位置と対応して,左から右の順に並ぶ
(1 = 最初の次元)
- 戻り値:
特定の次元値「0」の場合:
LBound は常に「1」を返し、
UBound は次元数を返します。
配列がサイズ未指定(
'array( )' か
'array( Any [, Any...] )' で宣言されている)の場合、
UBound は '0' を返します。
配列の任意の有効な次元値(1から最後の次元数まで)の場合:
(L|U)Bound は、指定された次元で、添え字として使える最小値と最大値を返します。
配列がサイズ未指定(
'array( )' か
'array( Any [, Any...] )' で宣言されている)の場合、
LBound は '0' を、
UBound は '-1' を返します。
無効な次元値の場合(次元番号は無関係):
要約した事例表:
配列の定義 | array( ) | array( Any , Any ) | array( 4 , 5 To 9 ) |
次元数 (x) | | (1) (2) | (1) (2) |
-----------------|---------------------|---------------------|---------------------|
LBound(array, 0) | 1 | 1 | 1 |
UBound(array, 0) | 0 | 0 (but not 2!) | 2 |
-----------------|---------------------|---------------------|---------------------|
LBound(array, 1) | 0 | 0 | 0 (by default) |
UBound(array, 1) | -1 | -1 | 4 |
-----------------|---------------------|---------------------|---------------------|
LBound(array, 2) | 0 | 0 | 5 |
UBound(array, 2) | -1 | -1 | 9 |
-----------------|---------------------|---------------------|---------------------|
LBound(array, k) | 0 | 0 | 0 |
UBound(array, k) | -1 | -1 | -1 |
for k<0 or k>2 | | | |
-----------------|---------------------|---------------------|---------------------|
- 使用例:
UBound( array , 0 ) を使うと、配列のサイズ(値 > 0)か(値 = 0)で、次元数(正の値)を簡単に判断することができます。
備考:
( ( LBound( array ) = 0 ) AND ( UBound( array ) = -1 ) ) Or
( @array( LBound( array ) ) = 0 ) とすると、配列のサイズが未指定であることを知ることができます。
次元の数が分かると、各次元の最小最大 2つの範囲の情報を安全に取得できるようになります。
配列のすべてのサイズ情報を表示するマクロの例:
#macro PRINT_ARRAY_SIZING (array)
If UBound( array , 0 ) = 0 Then
Print "'" & #array & "' un-sized"
Else
Print "'" & #array & "' sized with " & UBound( array , 0 ) & " dimension";
If UBound( array , 0 ) > 1 Then
Print "s";
End If
Print
For I As Integer = 1 To UBound( array , 0 )
Print " dimension nb: " & I
Print " lower bound: " & LBound( array , I )
Print " upper bound: " & UBound( array , I )
Next I
End If
#endmacro
Dim As Integer array1( )
PRINT_ARRAY_SIZING( array1 )
Print
Dim As Single array2( Any )
PRINT_ARRAY_SIZING( array2 )
Print
Dim As String array3( 4 , 5 To 9 )
PRINT_ARRAY_SIZING( array3 )
Print
Type UDT
Dim As Double array4( Any, Any, Any )
End Type
Dim As UDT u
PRINT_ARRAY_SIZING( u.array4 )
Print
ReDim u.array4( -7 To -3, -2 To 5, 6 To 9 )
PRINT_ARRAY_SIZING( u.array4 )
Print
Erase u.array4
PRINT_ARRAY_SIZING( u.array4 )
Print
Sleep
出力:
'array1' un-sized
'array2' un-sized
'array3' sized with 2 dimensions
dimension nb: 1
lower bound: 0
upper bound: 4
dimension nb: 2
lower bound: 5
upper bound: 9
'u.array4' un-sized
'u.array4' sized with 3 dimensions
dimension nb: 1
lower bound: -7
upper bound: -3
dimension nb: 2
lower bound: -2
upper bound: 5
dimension nb: 3
lower bound: 6
upper bound: 9
'u.array4' un-sized
- 注意:
多次元配列の最大次元数は 8です。
QB とは逆に、FB では多次元配列のデータをこの明確な順序で保存します。
最後のインデックスだけが異なる値が、メモリ上で連続しています(ロウ・メジャー・オーダー)。
範囲項目の代わりに
'Any' で宣言された配列は、現在、少なくともその次元数はすでに固定(ロック)されているにもかかわらず、
UBound (
'UBound( array , 0 ) = 0') で完全にサイズ未指定とみなされます。
さらに、この次元数の値は、配列記述子に設定されています。
この場合、
UBound( array , 0 ) は、
LBound (array , 0 ) = 0 and
UBound( array , 0 ) = -1 で、この値を返すことができました。
この挙動について、バグレポート(#853)が作成されました。
参考: