一个关于数组长度判断的问题

tombow 2013-03-07 03:51:09


Function isEmpty(ByRef ary) As Boolean
dim length as Integer : length = UBound(ary)
debug.Print length '对象数组这里会打印-1
End Function

'调用
dim myobj() as Object
dim mystr() as String
isEmpty(mystr) '正常报错了
isEmpty(myobj) '不报错,打印-1


为什么对象数组调用isEmpty 会不报错,而且会打印-1呢?
非对象数组像我理解一样,报错了。

求大侠们指点迷津,谢谢!
...全文
749 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
Tiger_Zhao 2013-03-18
  • 打赏
  • 举报
回复
原先的函数加上适当的错误处理完全可用。 作为通用函数要考虑 1)安全性——调用 API 用错参数可能直接导致崩溃。 2)性能——调用一次 API 通常没有纯 VB 代码快。
tombow 2013-03-14
  • 打赏
  • 举报
回复
引用 19 楼 chenjl1031 的回复:
换个思路,可以不用isEmpty: Visual Basic code ? 1234567891011 Option Explicit 'API判断数组为空或没有初始化 Private Declare Function SafeArrayGetDim Lib "oleaut32.dll" (ByRef saArray() As Any) As LongPriva……
函数参数是:ByRef ary as Variant,怎样调用SafeArrayGetDim 啊,SafeArrayGetDim 参数是数组.
tombow 2013-03-14
  • 打赏
  • 举报
回复
哦,可以了,以前不可以是这样定义:

function isEmptyArray(ByRef ary() as Variant)
end function
大哥,可以关注一下这个贴吗? http://bbs.csdn.net/topics/390391741
东方之珠 2013-03-14
  • 打赏
  • 举报
回复
换个思路,可以不用isEmpty:
Option Explicit
'API判断数组为空或没有初始化
Private Declare Function SafeArrayGetDim Lib "oleaut32.dll" (ByRef saArray() As Any) As Long
Private Sub Command1_Click()
    Dim tmp() As Object 'string
    If SafeArrayGetDim(tmp) = 0 Then
       Debug.Print "数组为空或没有初始化"
    Else
       Debug.Print "数组已初始化"
    End If
End Sub
Tiger_Zhao 2013-03-14
  • 打赏
  • 举报
回复
上面说错了,定长数组也是可以调用的!

对象数组可以调用的啊!
Tiger_Zhao 2013-03-14
  • 打赏
  • 举报
回复
是定长数组调用不了吧!
但是定长数组为什么要判断是否为空?它是定长的啊!
Tiger_Zhao 2013-03-13
  • 打赏
  • 举报
回复
暂且理解为楼主只贴了函数的片段,不对功能进行吐槽。
tombow 2013-03-13
  • 打赏
  • 举报
回复
引用 15 楼 Tiger_Zhao 的回复:
暂且理解为楼主只贴了函数的片段,不对功能进行吐槽。
这几天一直没关注这问题,谢谢大哥的回答!


function isEmptyArray(ByRef ary as Variant)

End If

对象数组调用不了,说类型不匹配,怎么写才支持所有类型的数组都能调用呢?
of123 2013-03-12
  • 打赏
  • 举报
回复
不建议这样的函数及调用方式。 如果要预期结果确定,就精确限定函数的适用类型。 如果要通用,就应该编写更复杂的代码进行判断和分支。
Tiger_Zhao 2013-03-11
  • 打赏
  • 举报
回复
引用 11 楼 milaoshu1020 的回复:
>isEmpty 进行 ReDim 就需要新建 SAFEARRAY 描述 请问ReDim操作是在哪里触发的?
不是一定调用。 而是该数组必须具备在函数内调用 ReDim 的功能,这是 VB 的设计。
嗷嗷叫的老马 2013-03-11
  • 打赏
  • 举报
回复
顶赵老虎兄 之前在一个群里也见到有人发一样的问题,我建议他直接比较对象数组与普通变量数组的内存,结果那人没理我,现在这个回答够清楚了
引用 9 楼 Tiger_Zhao 的回复:
越是“高级”的语言,封装得越厉害;一句简单的语句通常就对应了多步“低级”的操作。 首先,关于数组 VB 中的数组是对 SAFEARRAY 的封装,该结构是对数组的描述。 数组变量 myobj、mystr 则是指向 SAFEARRAY 的指针(SAFEARRAY*)。 UBound/LBound 函数其实就是读取或计算 SAFEARRAY 结构中的上下标信息,如……
lliai 2013-03-08
  • 打赏
  • 举报
回复
类型是String等,如果数值为NULL,那用UBOUND()会报错; 而“Object”是对象或目标类型,没有NULL。所以不报错。
milaoshu1020 2013-03-08
  • 打赏
  • 举报
回复
isEmpty 进行 ReDim 就需要新建 SAFEARRAY 描述 请问ReDim操作是在哪里触发的?
酷心 2013-03-08
  • 打赏
  • 举报
回复
引用 9 楼 Tiger_Zhao 的回复:
越是“高级”的语言,封装得越厉害;一句简单的语句通常就对应了多步“低级”的操作。 首先,关于数组 VB 中的数组是对 SAFEARRAY 的封装,该结构是对数组的描述。 数组变量 myobj、mystr 则是指向 SAFEARRAY 的指针(SAFEARRAY*)。 UBound/LBound 函数其实就是读取或计算 SAFEARRAY 结构中的上下标信息,如……
支持一下……
Tiger_Zhao 2013-03-08
  • 打赏
  • 举报
回复
越是“高级”的语言,封装得越厉害;一句简单的语句通常就对应了多步“低级”的操作。 首先,关于数组 VB 中的数组是对 SAFEARRAY 的封装,该结构是对数组的描述。 数组变量 myobj、mystr 则是指向 SAFEARRAY 的指针(SAFEARRAY*)。 UBound/LBound 函数其实就是读取或计算 SAFEARRAY 结构中的上下标信息,如果数组变量 myobj、mystr 的指针为 NULL 时就报错。 其次,关于参数的传递 isEmpty(ByRef ary) 完整书写是 isEmpty(ByRef ary As Variant) 。 VB 中的 Variant 是对 VARIANT 变体结构的封装,是通过描述对其他数据/变量进行包装(故意不用“封装”这个词避免与语言的封装混淆)来统一类型。 本例中就是包装成指向数组变量的指针(SAFEARRAY**),这样函数 isEmpty 内就能对数组进行包括 ReDim/Erase 之内的一切操作。 但是开始时两个数组变量都没初始化,isEmpty 进行 ReDim 就需要新建 SAFEARRAY 描述,让我们看看: a) isEmpty(mystr)   包装的 VARIANT 中描述为“字符串数组”,这样的 SAFEARRAY 没有什么特别的,可以直接新建 。 b) isEmpty(myobj)   包装的 VARIANT 中描述为“对象数组”,这样的 SAFEARRAY 还需要对象类型相关的描述,而这在 isEmpty 内是未知的。 VB 的解决方法就是在调用 isEmpty(myobj) 前自动进行初始化,新建一个元素个数为 0 的 SAFEARRAY 描述,这样 isEmpty 内的 ReDim 操作就没问题了。 结论就是:同样的调用,一个会对空数组初始化而一个不会。 牵涉点稍多,尽量简写了(花了数小时简化)。 能看懂的自然不用解释;不能看懂的也不要急,记住结论即可。 又:本回答应该有资格加精
酷心 2013-03-08
  • 打赏
  • 举报
回复
楼上没发现对于没有初始化的数组是会出错的吗?下标越界!除了Object类型……

Dim AryObj() As Object
Dim AryVar() As Variant
Dim AryStr() As String
Dim AryInt() As Integer
Dim AryLng() As Long
  Call MyisEmpty(AryObj)
  Call MyisEmpty(AryVar)
  Call MyisEmpty(AryStr)
  Call MyisEmpty(AryInt)
  Call MyisEmpty(AryLng)
楼主想问的意思为什么Object数组就不会报错,其他的类型就会? 我知道没有初始化数组用Ubound会报错,不过Object类型是否一定义就初始化了?还是其他原因,我也想知道……
赵4老师 2013-03-08
  • 打赏
  • 举报
回复
5楼选成C/C++ code了。
赵4老师 2013-03-08
  • 打赏
  • 举报
回复
Function MyisEmpty(ByRef ary) As Boolean
    dim length as Long

    if IsArray(ary) then
        length = UBound(ary) - LBound(ary)
    else
        length = 0
    end if
    debug.Print length   '对象数组这里会打印-1
    if length>0 then
      MyisEmpty=True
    else
      MyisEmpty=False
    end if
End Function
赵4老师 2013-03-08
  • 打赏
  • 举报
回复
Function MyisEmpty(ByRef ary) As Boolean
    dim length as Long

    if IsArray(ary) then
        length = UBound(ary) - LBound(ary)
    else
        length = 0
    end if
    debug.Print length   '对象数组这里会打印-1
    if length>0 then
      MyisEmpty=True
    else
      MyisEmpty=False
    end if
End Function
岭神 2013-03-07
  • 打赏
  • 举报
回复
不大明白...也想知道
加载更多回复(2)

7,785

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧