Skip to content

数组


多维容器类型。

概述

数组 是特殊类型的变量,作为多个值或 元素 的容器。数组可以存储任何类型的元素,且所有元素共享同一类型。例如,数组可以存储 Integer 元素或 Single 元素,但不能同时存储两者。这些元素通过表示其在数组中 位置Integer 值来访问(读取或写入)。数组有长度或 大小,等于它在任意给定时间存储的元素数量。定长 数组在其生命周期内具有固定的大小,而 变长 数组的大小可以动态变化。

元素和位置

数组存储的值即其元素。数组的每个元素都有对应的位置,该位置是从数组的 下界上界(含)的 Integer 值。这些位置用于通过 operator () 访问数组中的单个元素,该运算符接受一个位置并返回该位置元素的引用。数组中的有效位置大于或等于其下界,且小于或等于其上界。

start GeSHi

vb
' 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)
Next

end GeSHi

大小和边界

数组的大小等于它在任意给定时间存储的元素数量。数组的大小可以为零(0),意味着它当前不存储任何值——它是 空的。如果数组的大小大于零,则存储了相应数量的元素。数组的大小等于其上界与下界之差加一,即 ubound(array) - lbound(array) + 1

下界和上界不仅决定了数组的大小,还决定了单个元素的有效位置。例如,下界为零(0)、上界为四(4)的数组存储五(5)个元素,第一个元素在位置 0,最后一个在位置 4。这些边界可以在数组声明时指定,或者对某些数组通过调整数组大小来更改。数组的下界和上界可以分别使用 LboundUbound 获取。

创建或调整数组大小时,如果未指定下界,则默认为零(0)。

start GeSHi

vb
' 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) ;
Next

end GeSHi

定长与变长

数组有两种基本类型:定长变长。两者的主要区别在于定长数组的边界永远不能改变,即它们始终在相同位置存储相同数量的元素。变长数组的边界可以更改,影响存储的元素数量和/或元素的位置。

由于定长数组的大小永不改变,编译器会根据数组的存储类,选择在静态存储或程序栈上为数组元素分配内存。这是一个优势,因为创建这类数组的开销不包含任何运行时性能损耗。定长数组使用 ExternStaticDim 声明。至少必须指定上界,且所有边界必须是编译时常量值,例如数字字面量、Const 变量或 Enum 枚举值。

变长数组可以改变大小,因此编译器会在运行时在自由存储(堆)中为数组元素分配内存。这样做的优势当然是能够动态调整数组大小,但创建、调整大小或销毁时的运行时性能可能会有所不同。变长数组使用 ExternStaticDimRedim 声明。使用 ExternStaticDim 时,可以不指定下界和上界——这样会得到一个空数组——或者至少其中一个必须是变量值,例如 Integer 变量或 Function 结果。Redim 可通过给定不同的下界和/或上界来调整现有变长数组的大小。

start GeSHi

vb
' 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

多维数组

到目前为止讨论的数组都是一维的,即通过单个位置访问元素。一维数组可以看作一排简单的元素行。数组也可以有多个维度;使用两个或多个位置来访问数组的单个元素。二维数组使用两个位置(行位置和列位置)来引用单个元素,类似于网格或表格。三维数组使用三个位置(行、列,也许还有深度位置)来引用单个元素,类似于立方体。四维数组可以看作是一个或多个三维数组,以此类推。多维数组的声明方式与一维数组相同,只是指定了多个下界和上界范围。

多维数组的元素总数和总大小(以字节为单位)可以分别使用 ArrayLenArraySize 直接获取。

start GeSHi

vb
' 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'

汇总表示例:

vb
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

vb
#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

end 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 ) = 0UBound( array , 0 ) = -1

关于此行为,已提交了一个错误报告(#853)。

参见

返回 目录

基于 FreeBASIC 官方文档翻译 如有侵权请联系我们删除
FreeBASIC 是开源项目,与微软公司无隶属关系