数组
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgArrays
- 最后更新: 2024-05-19
多维容器类型。
概述
数组 是特殊类型的变量,作为多个值或 元素 的容器。数组可以存储任何类型的元素,且所有元素共享同一类型。例如,数组可以存储 Integer 元素或 Single 元素,但不能同时存储两者。这些元素通过表示其在数组中 位置 的 Integer 值来访问(读取或写入)。数组有长度或 大小,等于它在任意给定时间存储的元素数量。定长 数组在其生命周期内具有固定的大小,而 变长 数组的大小可以动态变化。
元素和位置
数组存储的值即其元素。数组的每个元素都有对应的位置,该位置是从数组的 下界 到 上界(含)的 Integer 值。这些位置用于通过 operator () 访问数组中的单个元素,该运算符接受一个位置并返回该位置元素的引用。数组中的有效位置大于或等于其下界,且小于或等于其上界。
start GeSHi
' Create an array of 3 elements all having the value zero (0.0f).
Dim array(1 To 3) As Single
' Assign a value to the first element.
array(1) = 1.2
' Output the values of all the elements ("1.2 0 0").
For position As Integer = 1 To 3
Print array(position)
Nextend GeSHi
大小和边界
数组的大小等于它在任意给定时间存储的元素数量。数组的大小可以为零(0),意味着它当前不存储任何值——它是 空的。如果数组的大小大于零,则存储了相应数量的元素。数组的大小等于其上界与下界之差加一,即 ubound(array) - lbound(array) + 1。
下界和上界不仅决定了数组的大小,还决定了单个元素的有效位置。例如,下界为零(0)、上界为四(4)的数组存储五(5)个元素,第一个元素在位置 0,最后一个在位置 4。这些边界可以在数组声明时指定,或者对某些数组通过调整数组大小来更改。数组的下界和上界可以分别使用 Lbound 和 Ubound 获取。
创建或调整数组大小时,如果未指定下界,则默认为零(0)。
start GeSHi
' Declares and initializes an array of four integer elements.
Dim array(3) As Integer = { 10, 20, 30, 40 }
' Outputs all of the element values (" 10 20 30 40").
For position As Integer = LBound(array) To UBound(array)
Print array(position) ;
Nextend GeSHi
定长与变长
数组有两种基本类型:定长 和 变长。两者的主要区别在于定长数组的边界永远不能改变,即它们始终在相同位置存储相同数量的元素。变长数组的边界可以更改,影响存储的元素数量和/或元素的位置。
由于定长数组的大小永不改变,编译器会根据数组的存储类,选择在静态存储或程序栈上为数组元素分配内存。这是一个优势,因为创建这类数组的开销不包含任何运行时性能损耗。定长数组使用 Extern、Static 和 Dim 声明。至少必须指定上界,且所有边界必须是编译时常量值,例如数字字面量、Const 变量或 Enum 枚举值。
变长数组可以改变大小,因此编译器会在运行时在自由存储(堆)中为数组元素分配内存。这样做的优势当然是能够动态调整数组大小,但创建、调整大小或销毁时的运行时性能可能会有所不同。变长数组使用 Extern、Static、Dim 和 Redim 声明。使用 Extern、Static 或 Dim 时,可以不指定下界和上界——这样会得到一个空数组——或者至少其中一个必须是变量值,例如 Integer 变量或 Function 结果。Redim 可通过给定不同的下界和/或上界来调整现有变长数组的大小。
start GeSHi
' Creates a fixed-length array that holds 5 single elements.
Const totalSingles = 5
Dim flarray(1 To totalSingles) As Single
' Creates an empty variable-length array that holds integer values.
Dim vlarray() As Integer
' Resizes the array to 10 elements.
ReDim vlarray(1 To 10)end GeSHi
多维数组
到目前为止讨论的数组都是一维的,即通过单个位置访问元素。一维数组可以看作一排简单的元素行。数组也可以有多个维度;使用两个或多个位置来访问数组的单个元素。二维数组使用两个位置(行位置和列位置)来引用单个元素,类似于网格或表格。三维数组使用三个位置(行、列,也许还有深度位置)来引用单个元素,类似于立方体。四维数组可以看作是一个或多个三维数组,以此类推。多维数组的声明方式与一维数组相同,只是指定了多个下界和上界范围。
多维数组的元素总数和总大小(以字节为单位)可以分别使用 ArrayLen 和 ArraySize 直接获取。
start GeSHi
' Take Care while initializing multi-dimensional array
Dim As Integer multidim(1 To 2,1 To 5) = {{0,0,0,0,0},{0,0,0,0,0}}end GeSHi
LBound 和 UBound 的详细用法
LBound / UBound 返回数组大小信息的下界/上界值:数组的维度数(可用索引数)以及每个维度的索引边界。数组名称在第一个参数中指定,维度选择在第二个参数中。
这些大小信息对定长数组(大小在编译时固定)和变长数组(某些大小在运行时可调整)都可用。
- 用法:
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 definition | array( ) | array( Any , Any ) | array( 4 , 5 To 9 ) |
Dimension nb (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 ) )
或:
( @array( LBound( array ) ) = 0 ) - 注意:自 fbc 1.20.0 起不再支持
仅用于判断数组是否未定义大小。
一旦确定了维度数,就可以安全地访问每个维度的两个边界信息。
显示数组所有大小信息的宏示例:
start GeSHi
#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
Sleepend GeSHi
输出:
'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 和 UBound( array , 0 ) = -1。
关于此行为,已提交了一个错误报告(#853)。
参见
返回 目录