fbc-int/array.bi インクルードファイルからの、定義済み構造(UDT)および手続き宣言を使って、配列記述子データ項目に、アクセスできます。
構文:
From
./inc/fbc-int/array.bi (for fbc versions >= 1.08):
# If __FB_LANG__ = "fb"
Namespace FBC
# endif
Const FB_MAXDIMENSIONS As Integer = 8
Type FBARRAYDIM
Dim As UInteger elements '' number of elements
Dim As Integer LBound '' dimension lower bound
Dim As Integer UBound '' dimension upper bound
End Type
Const FBARRAY_FLAGS_DIMENSIONS = &h0000000f '' number of entries allocated in dimTb()
Const FBARRAY_FLAGS_FIXED_DIM = &h00000010 '' array has fixed number of dimensions
Const FBARRAY_FLAGS_FIXED_LEN = &h00000020 '' array points to fixed-length memory
Const FBARRAY_FLAGS_RESERVED = &hffffffc0 '' reserved, do not use
Type FBARRAY
Dim As Any Ptr index_ptr '' @array(0, 0, 0, ... )
Dim As Any Ptr base_ptr '' start of memory at array lowest bounds
Dim As UInteger size '' byte size of allocated contents
Dim As UInteger element_len '' byte size of single element
Dim As UInteger dimensions '' number of dimensions
Dim As UInteger flags '' FBARRAY_FLAGS_*
'' take care with number of dimensions; fbc may allocate
'' a smaller descriptor with fewer than FB_MAXDIMENSIONS
'' in dimTb() if it is known at compile time that they
'' are never needed. Always respect number of
'' dimensions when accessing dimTb()
Dim As FBARRAYDIM dimTb(0 To FB_MAXDIMENSIONS-1)
End Type
Extern "rtlib"
Declare Function ArrayDescriptorPtr Alias "fb_ArrayGetDesc" _
( array() As Any ) As FBC.FBARRAY Ptr
Declare Function ArrayConstDescriptorPtr Alias "fb_ArrayGetDesc" _
( array() As Const Any ) As Const FBC.FBARRAY Ptr
End Extern
# If __FB_LANG__ = "fb"
End Namespace
# endif
用法:
#include once "fbc-int/array.bi"
using FBC
' then:
Dim pd As FBARRAY Ptr
...
pd = ArrayDescriptorPtr ( array() )
' or safer:
Dim pd As Const FBARRAY Ptr
...
pd = ArrayConstDescriptorPtr ( array() )
パラメータ:
pd
配列記述子へのポインターの名前
array
記述子にアクセスしたい配列の名前
内容:
コンパイル時に、fbc は配列記述子を割り当てて、配列に関する情報を保存し追跡します。
コンパイル時に次元数が不明な場合、全
FB_MAXDIMENSIONS が
dimTb() 項目に割り当てられます。
そうでなくて、コンパイル時に次元数がわかっている場合は、必要な次元数だけが割り当てられます。
したがって、割り当てられた
FBARRAY データは、宣言された
FBARRAY 構造よりも小さい場合があります:
allocated FBARRAY data size (in bytes)
= Sizeof(FBARRAY) - (FB_MAXDIMENSIONS - (FBARRAY.flags And FBARRAY_FLAGS_DIMENSIONS)) * Sizeof(FBARRAYDIM)
コンパイル時に次元数が不明な場合、完全な
FB_MAXDIMENSIONS が、
dimTb() 項目に、割り当てられます。
それ以外で、コンパイル時に次元数がわかっている場合は、必要な次元数のみが、割り当てられます。
したがって、割り当てられた
FBARRAY データは、宣言された
FBARRAY 構造よりも小さい場合があります。
配列が引数として手続きに渡される場合、配列記述子が、割り当てられます。
ただし、配列が静的で固定長であり、引数として渡されない場合、配列に関するすべての情報は、メモリ位置を含め、コンパイル時に既知であり、記述子の割り当ては、最適化されます。配列を含むすべての式が、コンパイル時定数だからです。
実行時に、配列記述子を割り当てることもできます。可変長配列項目メンバーを含む新しい UDT を割り当てる場合と同様です。
警告: 配列記述子(コンパイラの内部構造)のデータ値を変更することは、(特に上級ユーザーでない場合は)お勧めできません。
このため、
As Const FBARRAY Ptr (または
Var によって暗黙的に宣言された)として宣言された、ポインターを初期化する
ArrayConstDescriptorPtr() 関数を使う方が安全です。
FBARRAY.index_ptr
配列データへのポインター @array(0, 0, ...)。
このポインターは、配列の添え字を使ってオフセットを計算するときに使う、一種の仮想ポインターとして、実際の配列データの外側にある場合があります。
FBARRAY.base_ptr
配列の最下限での、配列のメモリへのポインタ。
実行時に割り当てられた可変長配列の場合、これは、割り当てられたメモリ領域(つまり malloc)を指します
FBARRAY.size
配列データの、合計サイズ(バイト単位)。
サイズは、配列内の要素の総数(すべての次元)に、要素の長さを掛けた値に等しくなります。
つまり size = dimTb(0).elements * element_len + dimTb(1).elements * element_len + ...
FBARRAY.element_len
個々の要素の、バイト単位のサイズ。
ゼロ以外の値に、設定する必要があります。
FBARRAY.dimensions
dimTb() テーブル内の有効な次元の数。
値がゼロ(0)の場合、dimTb() には FB_MAXDIMENSIONS が使えますが、配列にはまだ次元数が定義されていません。
最初の REDIM では、次元の数が設定されます。
FBARRAY.flags
flags 項目には、実行時に知る必要がある、配列記述子に関する情報が含まれています。
FBARRAY_FLAGS_DIMENSIONS :
dimTb() で割り当てられた要素の数を示す 4ビットの項目。
fbc がコンパイル時に、配列を表すために必要なのが
FB_MAXDIMENSIONS よりも少ない次元だと判断できる場合は、必要な次元の数だけが
dimTb() に割り当てられます。
配列記述子に割り当てられた実際のサイズは、次の方法で計算できます:
Sizeof(FBC.FBARRAY) - (FBC.FB_MAXDIMENSIONS - (FBC.ArrayDescriptorPtr(array())->flags And FBC.FBARRAY_FLAGS_DIMENSIONS)) * Sizeof(FBC.FBARRAYDIM)
FBARRAY_FLAGS_FIXED_DIM : このビットが設定されている場合、次元数が設定されて、
dimTb() で与えられるので、変更しないでください。
FBARRAY_FLAGS_FIXED_LEN : このビットが設定されていると、配列データは固定長で、サイズ変更または再割り当てしてはならないことを示します。
FBARRAY_FLAGS_RESERVED : 他のすべてのビットは、将来の使用のために予約されています。
FBARRAY.dimTb()
dimTb() は、各次元の境界を示す FBARRAYDIM の配列です。
コンパイル時に次元数が不明な場合、完全な FB_MAXDIMENSIONS が、dimTb() 項目に割り当てられます。
それ以外で、コンパイル時に次元数がわかっている場合は、必要な次元数のみが割り当てられます。
したがって、割り当てられた FBARRAY データは、宣言された FBARRAY 構造よりも小さい場合があります。
FBARRAYDIM.elements
次元内の要素の数。 すなわち (ubound-lbound+1)
FBARRAYDIM.lbound
下限は、この次元で、最小の有効な添え字です。
FBARRAYDIM.ubound
上限は、この次元で有効な、最大の添え字です。
ArrayDescriptorPtr( array() as any ) as FBC.FBARRAY ptr
配列記述子へのポインタを取得し、変更可能な FBC.ARRAY へのポインタを返します(こうして参照された配列記述子は、それが作成されたスコープの終わりまで有効です)。
ArrayConstDescriptorPtr( array() as const any ) as const FBC.FBARRAY ptr
配列記述子へのポインタを取得し、読み取り専用の FBC.ARRAY へのポインタを返します(こうして参照された配列記述子は、それが作成されたスコープの終わりまで有効です)。
例:
配列記述子のデータ項目へのアクセス機能を強調した、非常に単純な構文例(fbc バージョン >=
1.08 の場合):
#include "fbc-int/array.bi"
Sub printArrayDescriptor (ByVal p As Any Ptr, ByVal tabulation As Integer = 0, ByRef title As String = "")
Dim As FBC.FBARRAY Ptr pd = p
Dim As Integer t = 0
If title <> "" Then
Print title
t = 1
End If
Print Space((t ) * tabulation) & "[@array descriptor: @&h"; Hex(pd, 2 * SizeOf(Any Ptr)) & " / "; _
SizeOf(FBC.FBARRAY) - (8 - pd->dimensions) * 3 * SizeOf(Integer) & " bytes]"'
Print Space((t + 1) * tabulation) & "@array(all_null_indexes) =&h"; Hex(pd->index_ptr, 2 * SizeOf(Any Ptr))
Print Space((t + 1) * tabulation) & "@array(all_min_indexes) =&h"; Hex(pd->base_ptr, 2 * SizeOf(Any Ptr))
Print Space((t + 1) * tabulation) & "array_total_size_in_bytes ="; pd->size
Print Space((t + 1) * tabulation) & "array_element_size_in_bytes ="; pd->element_len
Print Space((t + 1) * tabulation) & "number_of_array_dimensions ="; pd->dimensions
Print Space((t + 1) * tabulation) & "fixed_len/fixed_dim/dimensions="; (pd->flags And FBC.FBARRAY_FLAGS_FIXED_LEN) Shr 5 & "/"; _
(pd->flags And FBC.FBARRAY_FLAGS_FIXED_DIM) Shr 4 & "/"; _
(pd->flags And FBC.FBARRAY_FLAGS_DIMENSIONS)
For i As Integer = 0 To pd->dimensions - 1
Print Space((t + 1) * tabulation) & "[dimension number:"; i + 1; "]"
Print Space((t + 2) * tabulation) & "number_of_elements="; pd->dimTb(i).elements
Print Space((t + 2) * tabulation) & "min_index ="; pd->dimTb(i).LBound
Print Space((t + 2) * tabulation) & "max_index ="; pd->dimTb(i).UBound
Next i
End Sub
Screen 0
Width , 35
Dim As LongInt test1(0 To 9, 1 To 100)
printArrayDescriptor(FBC.ArrayDescriptorPtr(test1()), 4, "'Dim As Longint test1(0 to 9, 1 to 100)':")
Sleep
Cls
Dim As LongInt test2()
printArrayDescriptor(FBC.ArrayDescriptorPtr(test2()), 4, "'Dim As Longint test2()':")
Print
ReDim test2(0 To 9, 1 To 100)
printArrayDescriptor(FBC.ArrayDescriptorPtr(test2()), 4, "'Redim test2(0 to 9, 1 to 100)':")
Sleep
Cls
Dim As LongInt test3(Any, Any)
printArrayDescriptor(FBC.ArrayDescriptorPtr(test3()), 4, "'Dim As Longint test3(Any, Any)':")
Print
ReDim test3(0 To 9, 1 To 100)
printArrayDescriptor(FBC.ArrayDescriptorPtr(test3()), 4, "'Redim test3(0 to 9, 1 to 100)':")
Sleep
出力例 (32-bit):
'Dim As Longint test1(0 to 9, 1 to 100)':
[@array descriptor: @&h0019DE70 / 48 bytes]
@array(all_null_indexes) =&h0019DE98
@array(all_min_indexes) =&h0019DEA0
array_total_size_in_bytes =8000
array_element_size_in_bytes =8
number_of_array_dimensions =2
fixed_len/fixed_dim/dimensions=1/1/2
[dimension number: 1]
number_of_elements=10
min_index = 0
max_index = 9
[dimension number: 2]
number_of_elements=100
min_index = 1
max_index = 100
'Dim As Longint test2()':
[@array descriptor: @&h0019DDF8 / 24 bytes]
@array(all_null_indexes) =&h00000000
@array(all_min_indexes) =&h00000000
array_total_size_in_bytes =0
array_element_size_in_bytes =8
number_of_array_dimensions =0
fixed_len/fixed_dim/dimensions=0/0/8
'Redim test2(0 to 9, 1 to 100)':
[@array descriptor: @&h0019DDF8 / 48 bytes]
@array(all_null_indexes) =&h01FD2AB8
@array(all_min_indexes) =&h01FD2AC0
array_total_size_in_bytes =8000
array_element_size_in_bytes =8
number_of_array_dimensions =2
fixed_len/fixed_dim/dimensions=0/0/8
[dimension number: 1]
number_of_elements=10
min_index = 0
max_index = 9
[dimension number: 2]
number_of_elements=100
min_index = 1
max_index = 100
'Dim As Longint test3(Any, Any)':
[@array descriptor: @&h0019DDC8 / 48 bytes]
@array(all_null_indexes) =&h00000000
@array(all_min_indexes) =&h00000000
array_total_size_in_bytes =0
array_element_size_in_bytes =8
number_of_array_dimensions =2
fixed_len/fixed_dim/dimensions=0/1/2
[dimension number: 1]
number_of_elements=0
min_index = 0
max_index = 0
[dimension number: 2]
number_of_elements=0
min_index = 0
max_index = 0
'Redim test3(0 to 9, 1 to 100)':
[@array descriptor: @&h0019DDC8 / 48 bytes]
@array(all_null_indexes) =&h01FD4C20
@array(all_min_indexes) =&h01FD4C28
array_total_size_in_bytes =8000
array_element_size_in_bytes =8
number_of_array_dimensions =2
fixed_len/fixed_dim/dimensions=0/1/2
[dimension number: 1]
number_of_elements=10
min_index = 0
max_index = 9
[dimension number: 2]
number_of_elements=100
min_index = 1
max_index = 100
バージョン:
方言差:
QBからの違い:
参照: