Skip to content

向过程传递数组


声明/定义数组参数并向过程传递数组实参

数组符号名称的语法

作为过程声明中的参数:

( [ any [, any...] ] ) as datatype

array_name( [ any [, any...] ] ) as datatype

作为过程定义中的参数:

array_name( [ any [, any...] ] ) as datatype

作为过程调用中的实参:

array_name()

括号(即使为空)是必需的,用于指定参数/实参是数组。

数组符号名称的用法

声明带数组参数的过程时:

declare { sub | function } proc_name ... ( ( [ any [, any...] ] ) as datatype , ... ) [ ... ]

declare { sub | function } proc_name ... ( array_parameter_name( [ any [, any...] ] ) as datatype , ... ) [ ... ]

定义带数组参数的过程时:

{ sub | function } proc_name ... ( array_parameter_name( [ any [, any...] ] ) as datatype , ... ) [ ... ]

向过程传递数组实参时:

sub_name ( array_argument_name() , ... )

sub_name array_argument_name() , ...

funct_name ( array_argument_name() , ... )

funct_name array_argument_name() , ...

... funct_name ( array_argument_name() , ... ) [ ... ]

注意(与任何参数/实参列表的规则相同):

声明/定义过程时,括号包围非空参数列表是必须的。

调用子程序时,括号包围实参列表(空或非空)是可选的。

将函数作为子程序调用时(不使用返回变量),规则与子程序相同。

在表达式中调用函数时(使用返回值),括号包围非空实参列表是必须的。

但是,通常的惯例是始终在过程名称后使用括号(空或非空),以表示过程调用。

描述

数组参数前不能有 byvalbyref 关键字,因为数组的传递方式与普通参数不同。变量按值或按引用传递,而数组按描述符传递(见下文)。实际上,当数组被传递给过程时,传递的是对其描述符的引用。

传入数组的所有元素都可以被修改,这些更改会在调用层级中反映。也许应该允许类似于可变长度字符串(也是按描述符传递)的 byref

没有直接按值传递数组的方法。将传入的数组参数声明为 as constant 只会禁止在过程体中进行任何修改。变通方法是传递用户自己制作的数组副本。

注意:

函数返回值不能是数组类型变量。

定长字符串数组不能传递给过程。

zstring/wstring 数组不能简单地传递给过程,因为 zstring/wstring 的大小不会传递(编译器在过程体中默认使用 "as zstring/wstring * 1" 类型)。这目前是一个 bug,因为编译器会静默失败,同时错误地计算过程体中每个数组元素的地址(除了第一个)。

数组描述符(仅供参考):

对于定长数组,描述符仅用于将数组传递给过程(否则编译器不使用它,因为数组的固定特性是已知的)。

对于可变长度数组,描述符始终使用(数组描述符是唯一定义数组特性的东西)。

数组描述符具有以下结构(每项用 Any PtrUinteger 编码,lbound 和 ubound 除外,它们用 Integer 编码):

  • 指向真实或虚拟元素的指针:@array(0, 0, ...)

  • 指向第一个真实元素的指针:@array(lbound1, lbound2, ...)

  • "全局"字节大小:(ubound1 - lbound1 + 1) × (ubound2 - lbound2 + 1) × ... × (1个元素的字节大小)

  • 一个元素的字节大小

  • 维数

  • 标志(*):数组指向定长内存(1位)/ 数组的维数在第一次声明时确定 / 描述符中分配的维数(4位)

然后对于每个维:

  • 元素个数:(ubound - lbound + 1)

  • lbound

  • ubound

(*):fbc 版本 >= 1.08 有额外成员字段(Uinteger

(请参阅 fbc 版本 >= 1.07 的包含文件 ./inc/fbc-int/array.bi

有关更多信息,请参见 FBARRAY(数组描述符结构和访问)

示例

start GeSHi

vb
Declare Sub splitString(ByVal As String, (Any) As String, ByVal As UByte = Asc(","))

Dim As String s = "Programmer's Guide/Variables and Datatypes/Arrays/Passing Arrays to Procedures"
Dim As String array(Any)

splitString(s, array(), Asc("/"))

Print "STRING TO SPLIT:"
Print s
Print
Print "RESULT ARRAY FROM SPLITTING:"
For i As Integer = LBound(array) To UBound(array)
    Print i, array(i)
Next i

Sleep

Sub splitString(ByVal source As String, destination(Any) As String, ByVal delimitor As UByte)
    Do
        Dim As Integer position = InStr(1, source, Chr(delimitor))
        ReDim Preserve destination(UBound(destination) + 1)
        If position = 0 Then
            destination(UBound(destination)) = source
            Exit Do
        End If
        destination(UBound(destination)) = Left(source, position - 1)
        source = Mid(source, position + 1)
    Loop
End Sub

end GeSHi

参见

返回 目录

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