分享:VB6如何判断数组是否初始化
vb吧
全部回复
仅看楼主
吧务
level 12
sunruisunrui 楼主
2020年03月04日 14点03分 1
level 15
这个写法以前见过,感觉挺bug的
理论上来说,VB是不支持指针直接运算的,需要用隐藏函数(如VarPtr)才能取指针并进行运算;但是这里却可以对数组名这个指针进行Not运算……未初始化的指针值为0,取反之后就是-1
2020年03月05日 02点03分 2
我是从国外的论坛借鉴过来的。
2020年03月05日 03点03分
@sunruisunrui 这个方法的确比SafeArrayGetDim和varptr后Copymemory要高效
2020年03月05日 10点03分
level 13
Declare Function SafeArrayGetDim Lib "oleaut32.dll" (ByRef saArray() As Any) As Long
如果数组已经初始化,则返回非0,否则返回0。
2020年03月05日 06点03分 3
不行的,SafeArrayGetDim 的返回值是UINT16,不是Long,会导致数组地址的高位截断,如果非空数组的地址刚好的低16位为0,你就出BUG了。
2025年04月23日 03点04分
level 13
刚刚测试了下,用not数组名来判断数组为空,遇到bug了。只要not 数组名后,对single类型变量赋值,再debug.print 输出就会出现表达式太复杂了,但是编译就没问题了
2020年03月06日 14点03分 4
有意思
2020年03月07日 02点03分
不只是single。但是我开始是没有问题的。是不是数组没初始化的时候,没有数据类型,取反后给了错误的指针。
2025年04月23日 07点04分
level 1
'------------------------------------------------------------
'函数名:IsInitArr
'类型:Boolean
'参数:
' Arr-必选参数,Variant,任意数组
Public Function IsInitArr(Arr As Variant) As Boolean
'返回数组 Arr 是否已经初始化,若是则返回 True,否则返回 False
If IsArray(Arr) Then
On Error Resume Next
'--------------------------------------------------
'IsInitArr = UBound(Arr)
'这是为了排除 Array() 这种特殊情况
'其范围被认为是 0 To -1,但仍然是越界的
IsInitArr = UBound(Arr) >= LBound(Arr)
'--------------------------------------------------
If Err.Number = 9 Then IsInitArr = False
Else
Throw 5, "参数 Arr 必须是数组类型而不能是 " & TypeName(Arr) & " 类型"
End If
End Function
'------------------------------------------------------------
2026年02月13日 08点02分 6
你这个做法已经过时十几年了,既复杂又低效。最高效的做法是 If Not Not arr Then ...,次一点点的做法是用msvbvm60.tlb的ArrPtr(取和修改数组地址函数,与StrPtr、ObjPtr对应)。
2026年03月26日 00点03分
看楼下,和楼上的方法类似
2026年03月26日 04点03分
@yjryym 你猜你说的这些东西我知不知道?你猜猜我为什么要写这玩意儿?你考虑没考虑过VB6是有Variant的,数组是可以放在Varaint里的(不是Variant数组,而是存了数组的Variant),Dim a As Variant: a = Array(): Debug.Print Not Not a 你试试会发生什么,分分钟实时错误13。你再试试用我这个能不能解决
2026年04月12日 08点04分
@yjryym 而且 Not Not 还大概率触发奇怪的实时错误16“表达式太复杂”,至于你说的什么ArrPtr(我猜是Public Declare Function VarPtrArray Lib "msvbvm60.dll" Alias "VarPtr" ……),动态数组就算是空的也是有地址的,你用这东西获取SafeArray结构体指针,再读取维度和下标字段,这才是真正的复杂又低效。有这功夫我还不如直接SafeArrayGetDim()呢
2026年04月12日 08点04分
level 12
编译后百万次16毫秒左右,再想高效就得上汇编了,奈何VB6原生不支持,也不必搞那么麻烦
楼上的代码也试过,如果数组已初始化效率比这个稍差点也还可以,如果数组未初始化触发异常的话效率直降百倍
2026年04月24日 13点04分 9
不需要上汇编,上msvbvm60.tlb就行了。msvbvm60.tlb的ArrPtr属性直接映射msvbvm60.dll的GetMem4和PutMem4,可以直接高效任意读写任何强数组类型的SafeArray地址(空数组的地址为0)。
2026年05月11日 01点05分
1