向过程传递数组
- 来源: https://www.freebasic.net/wiki/wikka.php?wakka=ProPgPassingArrays
- 最后更新: 2022-05-30
声明/定义数组参数并向过程传递数组实参
数组符号名称的语法
作为过程声明中的参数:
( [ 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() , ... ) [ ... ]
注意(与任何参数/实参列表的规则相同):
声明/定义过程时,括号包围非空参数列表是必须的。
调用子程序时,括号包围实参列表(空或非空)是可选的。
将函数作为子程序调用时(不使用返回变量),规则与子程序相同。
在表达式中调用函数时(使用返回值),括号包围非空实参列表是必须的。
但是,通常的惯例是始终在过程名称后使用括号(空或非空),以表示过程调用。
描述
数组参数前不能有 byval 或 byref 关键字,因为数组的传递方式与普通参数不同。变量按值或按引用传递,而数组按描述符传递(见下文)。实际上,当数组被传递给过程时,传递的是对其描述符的引用。
传入数组的所有元素都可以被修改,这些更改会在调用层级中反映。也许应该允许类似于可变长度字符串(也是按描述符传递)的 byref。
没有直接按值传递数组的方法。将传入的数组参数声明为 as constant 只会禁止在过程体中进行任何修改。变通方法是传递用户自己制作的数组副本。
注意:
函数返回值不能是数组类型变量。
定长字符串数组不能传递给过程。
zstring/wstring 数组不能简单地传递给过程,因为 zstring/wstring 的大小不会传递(编译器在过程体中默认使用 "as zstring/wstring * 1" 类型)。这目前是一个 bug,因为编译器会静默失败,同时错误地计算过程体中每个数组元素的地址(除了第一个)。
数组描述符(仅供参考):
对于定长数组,描述符仅用于将数组传递给过程(否则编译器不使用它,因为数组的固定特性是已知的)。
对于可变长度数组,描述符始终使用(数组描述符是唯一定义数组特性的东西)。
数组描述符具有以下结构(每项用 Any Ptr 或 Uinteger 编码,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
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 Subend GeSHi
参见
返回 目录