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

FreeBASIC FBARRAY (配列記述子の構造とアクセス)

目次→実行時ライブラリー参考→配列関連FBARRAY (array descriptor structure and access)←オリジナル・サイト

FBARRAY (配列記述子の構造とアクセス) 左にメニュー・フレームが表示されていない場合は、ここをクリックして下さい

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

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_MAXDIMENSIONSdimTb() 項目に割り当てられます。
そうでなくて、コンパイル時に次元数がわかっている場合は、必要な次元数だけが割り当てられます。
したがって、割り当てられた 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からの違い: 参照:
配列関連に戻る
←リンク元に戻る プログラム開発関連に戻る

ページ歴史:2024-01-12 11:11:04
日本語翻訳:WATANABE Makoto、原文著作者:fxm

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

表示-非営利-継承