Как я определяю, инициализируется ли массив в VB6?

В Java все находится в форме класса.

Если вы хотите использовать любой объект, тогда у вас есть две фазы:

  1. Объявить
  2. Инициализация

Пример:

  • Объявление: Object a;
  • Инициализация: a=new Object();

То же самое для концепции массива

  • Объявление: Item i[]=new Item[5];
  • Инициализация: i[0]=new Item();

Если вы не дают секцию инициализации, тогда возникает NullpointerException.

52
задан Fionnuala 12 September 2012 в 00:30
поделиться

8 ответов

Вот то, с чем я пошел. Это является подобным GSerg's ответ , но использует лучше зарегистрированную API-функцию CopyMemory и является совершенно автономным (можно просто передать массив, а не ArrPtr (массив) к этой функции). Это действительно использует функцию VarPtr, которую Microsoft предостерегает от , но это - приложение только для XP, и это работает, таким образом, я не заинтересован.

Да, я знаю, что эта функция примет что-либо, что Вы бросаете в нее, но я оставлю проверку ошибок как осуществление для читателя.

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
  (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Public Function ArrayIsInitialized(arr) As Boolean

  Dim memVal As Long

  CopyMemory memVal, ByVal VarPtr(arr) + 8, ByVal 4 'get pointer to array
  CopyMemory memVal, ByVal memVal, ByVal 4  'see if it points to an address...  
  ArrayIsInitialized = (memVal <> 0)        '...if it does, array is intialized

End Function
14
ответ дан Community 7 November 2019 в 09:28
поделиться

Примечание: код был обновлен, исходная версия может быть найдена в история пересмотра (не, что полезно найти его). Обновленный код не зависит от недокументированного GetMem4 функция и правильно дескрипторы массивы всех типов.

Примечание для пользователей VBA: Этот код для VB6, который никогда не получал обновление x64. Если Вы намереваетесь использовать этот код для VBA, см. https://stackoverflow.com/a/32539884/11683 для версии VBA. Необходимо будет только взять CopyMemory объявление и эти pArrPtr функция, оставляя остальных.

я использую это:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(ByRef Destination As Any, ByRef Source As Any, ByVal length As Long)

Private Const VT_BYREF As Long = &H4000&

' When declared in this way, the passed array is wrapped in a Variant/ByRef. It is not copied.
' Returns *SAFEARRAY, not **SAFEARRAY
Public Function pArrPtr(ByRef arr As Variant) As Long
  'VarType lies to you, hiding important differences. Manual VarType here.
  Dim vt As Integer
  CopyMemory ByVal VarPtr(vt), ByVal VarPtr(arr), Len(vt)

  If (vt And vbArray) <> vbArray Then
    Err.Raise 5, , "Variant must contain an array"
  End If

  'see https://msdn.microsoft.com/en-us/library/windows/desktop/ms221627%28v=vs.85%29.aspx
  If (vt And VT_BYREF) = VT_BYREF Then
    'By-ref variant array. Contains **pparray at offset 8
    CopyMemory ByVal VarPtr(pArrPtr), ByVal VarPtr(arr) + 8, Len(pArrPtr)  'pArrPtr = arr->pparray;
    CopyMemory ByVal VarPtr(pArrPtr), ByVal pArrPtr, Len(pArrPtr)          'pArrPtr = *pArrPtr;
  Else
    'Non-by-ref variant array. Contains *parray at offset 8
    CopyMemory ByVal VarPtr(pArrPtr), ByVal VarPtr(arr) + 8, Len(pArrPtr)  'pArrPtr = arr->parray;
  End If
End Function

Public Function ArrayExists(ByRef arr As Variant) As Boolean
  ArrayExists = pArrPtr(arr) <> 0
End Function

Использование:

? ArrayExists(someArray)

Ваш код, кажется, делает то же (тестирующий на SAFEARRAY ** являющийся ПУСТЫМ), но способом который я рассмотрел бы ошибкой компилятора:)

24
ответ дан GSerg 7 November 2019 в 09:28
поделиться
Dim someArray() as Integer    

If someArray Is Nothing Then
    Debug.print "this array is not initialised"
End If
-8
ответ дан Andrew Harmel-Law 7 November 2019 в 09:28
поделиться

, Если массив является массивом строк, можно использовать Соединение () метод как тест:

Private Sub Test()

    Dim ArrayToTest() As String

    MsgBox StringArrayCheck(ArrayToTest)     ' returns "false"

    ReDim ArrayToTest(1 To 10)

    MsgBox StringArrayCheck(ArrayToTest)     ' returns "true"

    ReDim ArrayToTest(0 To 0)

    MsgBox StringArrayCheck(ArrayToTest)     ' returns "false"

End Sub


Function StringArrayCheck(o As Variant) As Boolean

    Dim x As String

    x = Join(o)

    StringArrayCheck = (Len(x) <> 0)

End Function
-1
ответ дан highlycaffeinated 7 November 2019 в 09:28
поделиться

Оба метода GSerg и Raven являются недокументированными взломами, но так как Visual BASIC 6 больше не разрабатывается тогда, это не проблема. Однако пример Raven не работает над всеми машинами. Необходимо протестировать как это.

, Если (Не someArray) =-1 Тогда

На некоторых машинах это возвратит нуль на других некоторое большое отрицательное число.

8
ответ дан RS Conley 7 November 2019 в 09:28
поделиться

Я нашел это:

Dim someArray() As Integer

If ((Not someArray) = -1) Then
  Debug.Print "this array is NOT initialized"
End If

Редактирование : Конли RS указал в его ответ , который (Не someArray) будет иногда возвращаться 0, таким образом, необходимо будет использовать ((Не someArray) =-1).

13
ответ дан Community 7 November 2019 в 09:28
поделиться

Я просто думал об этом. Достаточно простой, никакие вызовы API не необходимы. Какие-либо проблемы с ним?

Public Function IsArrayInitialized(arr) As Boolean

  Dim rv As Long

  On Error Resume Next

  rv = UBound(arr)
  IsArrayInitialized = (Err.Number = 0)

End Function

Редактирование : Я действительно обнаруживал дефект со связанным с поведением функции Разделения (на самом деле, я назову его дефектом в функции Разделения). Возьмите этот пример:

Dim arr() As String

arr = Split(vbNullString, ",")
Debug.Print UBound(arr)

, Каково значение Ubound (прибытие) в этой точке? Это-1! Так, передача этого массива к этой функции IsArrayInitialized возвратила бы true, но пытающийся получить доступ к прибытию (0) вызовет нижний индекс из ошибки диапазона.

17
ответ дан raven 7 November 2019 в 09:28
поделиться

Так как требуемый комментарий здесь отправит ответ.

Корректный ответ кажется, от @raven:

Dim someArray() As Integer

If ((Not someArray) = -1) Then
  Debug.Print "this array is NOT initialized"
End If

, Когда документация или Google сразу не возвращают объяснение, люди склонны называть это взломом. Хотя, что, кажется, объяснение, то, что Не не только Логичны, это - также Побитовый оператор, таким образом, это обрабатывает разрядное представление структур, а не булевские переменные только.

, Например, другой битовой операции здесь:

Dim x As Integer
x = 3 And 5 'x=1

Так вышеупомянутое И также рассматривается как побитовый оператор.

, Кроме того, и ценность для проверки, даже если не непосредственно связанный с этим,

оператор Not может быть перегружен, что означает, что класс или структура могут переопределить свое поведение, когда ее операнд имеет тип того класса или структуры. Перегрузка

Соответственно, Не интерпретирует массив как его поразрядное представление, и это отличает вывод, когда массив пуст или не как по-другому в форме числа со знаком. Таким образом, можно считать, что это не взлом, просто недокументация массива поразрядное представление, которое Не здесь выставляет и использует в своих интересах.

Не берет единственный операнд и инвертирует все биты, включая знаковый бит, и присваивает то значение результату. Это означает, что для положительных чисел со знаком, Не всегда возвращает отрицательное значение, и для отрицательных чисел, Не всегда возвращает положительное или нулевое значение. Логичный Поразрядный

решавший отправить, так как это предложило новый подход, который может быть расширенным, завершился или корректировался любым, у кого есть доступ к тому, как массивы представлены в их структуре. Таким образом, если кто-либо предлагает доказательство, оно на самом деле не предназначается для массивов, которые будут рассматривать Не поразрядно, мы должны принять его как не взлом и на самом деле как лучше всего чистый ответ, если они делают или не предлагают поддержки этой теории, если это - конструктивный комментарий к этому, приветствуется, конечно.

1
ответ дан 7 November 2019 в 09:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: