FreeBASIC マニュアルのトップに戻る

FreeBASIC ProPgArrays

目次→教本→プログラマーのための案内Arrays←オリジナル・サイト

配列の概要 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

←リンク元に戻る プログラム開発関連に戻る

多次元の入れ物の形式。

概要
配列は、複数の値や要素を格納できる、特別な種類の変数です。
配列はどんな型の要素でも格納することができます。その全ての要素は、同じ型を共有します。
たとえば、配列は、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 に格納されます。
これらの範囲は、配列の宣言時に指定しますが、配列によっては、配列のサイズを変更することもできます。
配列の下限と上限は、それぞれ LboundUbound を使って取得できます。

配列を作ったり、大きさを変更するときに、下界を指定しないと、下限は、デフォルトで、ゼロ (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 するかを選択します。
固定長配列を作るコストには、実行時の悪影響がないため、これは利点です。
固定長配列は、ExternStaticDim を使って、宣言します。
少なくとも、上限を指定しなければなりません。そして、上限・下限は、コンパイル時に定数値(例えば数値直定数、Const 変数、または Enum 列挙)でなければなりません。

可変長配列は、大きさを変えることができるので、コンパイラは、実行時に、空いている貯蔵場で、配列要素に記憶域を割り当てるほうを選択します。
この利点は、動的に配列サイズを変更できることです。しかし、配列が作成、サイズ変更、破棄されるとき、実行時性能が変わってきます。
可変長配列は、ExternStaticDimRedim を使って宣言します。
ExternStatic または 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)-- を使います。
四次元配列は、複数の三次元配列と考えることができます。
多次元配列は、一次元の配列と同様に宣言しますが、複数の下限と上限の範囲を指定する点が、異なっています。
多次元配列の要素の総数と合計サイズ(バイト単位)は、それぞれ ArrayLenArraySize をって直接取得できます。

' 多次元の配列を初期化している点に、注意してください。
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' を返します。

無効な次元値の場合(次元番号は無関係):
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)が作成されました。

参考:
プログラマーのための案内に戻る
←リンク元に戻る プログラム開発関連に戻る

ページ歴史:2021-12-18 14:03:38
日本語翻訳:WATANABE Makoto、原文著作者:JeffMarshall

ホームページのトップに戻る

表示-非営利-継承