Проверить массив

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Тимофей
Обычный пользователь
Обычный пользователь
 
Сообщения: 83
Зарегистрирован: 01.03.2004 (Пн) 10:01
Откуда: Киров

Проверить массив

Сообщение Тимофей » 01.10.2004 (Пт) 9:07

Как проверить заполнен массив или нет.
Массив предварительно объявлен неявно (без указания размерности).

Aleksej
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 191
Зарегистрирован: 03.06.2003 (Вт) 9:58

Сообщение Aleksej » 01.10.2004 (Пт) 9:14

Функция UBound

Возвращает значение типа Long, содержащий максимальный доступный индекс.

Тимофей
Обычный пользователь
Обычный пользователь
 
Сообщения: 83
Зарегистрирован: 01.03.2004 (Пн) 10:01
Откуда: Киров

Сообщение Тимофей » 01.10.2004 (Пт) 10:42

Я же говорю, что массив объявлен неявно (значит неуказана его размерность). И попытка узнать его UBound выдаст ошибку.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 01.10.2004 (Пт) 10:53

Ты еще не читал наших апостолов (GSerg и иже с ними? :) )? Срочно в статьи, там как раз есть пример, как узнать, инициализирован ли массив или нет.
Lasciate ogni speranza, voi ch'entrate.

Тимофей
Обычный пользователь
Обычный пользователь
 
Сообщения: 83
Зарегистрирован: 01.03.2004 (Пн) 10:01
Откуда: Киров

Сообщение Тимофей » 01.10.2004 (Пт) 12:15

Нашел в статьях, спасибо.

Ruslan Demidow
Мужчина!
Мужчина!
Аватара пользователя
 
Сообщения: 987
Зарегистрирован: 25.03.2004 (Чт) 13:39
Откуда: N.Novgorod

Сообщение Ruslan Demidow » 01.10.2004 (Пт) 12:39

Тимофей писал(а):Нашел в статьях, спасибо.

Что-то я не понял, а где эти статьи? Искал - не нашёл. Может плохо искал? :oops:
Это Ж-ж-ж-ж неспроста (с) Винни-Пух

Тимофей
Обычный пользователь
Обычный пользователь
 
Сообщения: 83
Зарегистрирован: 01.03.2004 (Пн) 10:01
Откуда: Киров

Сообщение Тимофей » 01.10.2004 (Пт) 12:52


Ruslan Demidow
Мужчина!
Мужчина!
Аватара пользователя
 
Сообщения: 987
Зарегистрирован: 25.03.2004 (Чт) 13:39
Откуда: N.Novgorod

Сообщение Ruslan Demidow » 01.10.2004 (Пт) 13:08

Тимофей писал(а):Лови
http://vbstreets.ru/VB/Articles/65977.aspx
Ах это! Я смотрел (именно, что смотрел), потому как
==================
Эта статья предполагает, что вы знакомы с функциями Get/PutMem и принципом получения параметров по их смещению с стеке
==================
А вот именно с этим я не знаком, даже понаслышке. И если честно сказать, из кода мало чего понял.
Ну да ладно. Разберусь.
А за помощь СПАСИБО. :)
Это Ж-ж-ж-ж неспроста (с) Винни-Пух

codemaster
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 604
Зарегистрирован: 13.02.2004 (Пт) 13:35

Сообщение codemaster » 02.10.2004 (Сб) 10:53

alibek писал(а):Ты еще не читал наших апостолов (GSerg и иже с ними? :) )? Срочно в статьи, там как раз есть пример, как узнать, инициализирован ли массив или нет.



Есть одно маленькое но:

к сожалению автор вопроса не написал тип массива и предполагаемый (ожидаемый) размер.

В случае с типом arr() as string
произойдет перевод BSTR в ABSTR
и если массив будет не путым а большим тормоза обеспечены.

( В статье это кстати выдается за "фишку" но может я что то не понимаю )

так что единственно правильный вариант исходя из быстродействия прогр. Ubound() и обработать ошибку если массив пустой.

P.S. Если идея в том что с проверкой массива создается пауза в программе то вариант GSerg несомненно лучше.


Жалко что в этом форуме нет места для обсуждения статей.
но это вопрос скорее к модераторам.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 02.10.2004 (Сб) 12:26

codemaster писал(а):Жалко что в этом форуме нет места для обсуждения статей.
но это вопрос скорее к модераторам.

Было бы наиболее логичным завести отдельный раздел - "Обсуждение статей", без права создавать новые топики, и с правом писать незарегистрированным пользователям. А внизу каждой статьи давать ссылку на соответствующий ей топик.
А то сейчас получается, что vbstreets.ru и bbs.vbstreets.ru - два разных и никак друг с другом не связанных проекта.
Изображение

gaidar
System Debugger
System Debugger
 
Сообщения: 3152
Зарегистрирован: 23.12.2001 (Вс) 13:22

Сообщение gaidar » 02.10.2004 (Сб) 14:54

Думали уже над этим. Я так и собирался сделать, но со всеми статьями - лень перелопачивать.

Новые статьи будут иметь такие ссылки.
The difficult I’ll do right now. The impossible will take a little while. (c) US engineers in WWII
I don't always know what I'm talking about, but I know I'm right. (c) Muhammad Ali

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 02.10.2004 (Сб) 16:44

gaidar писал(а):Новые статьи будут иметь такие ссылки.

Здорово! :cheers:

Осталось только поиск по русским буквам наладить ;-)
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 03.10.2004 (Вс) 13:18

codemaster писал(а):к сожалению автор вопроса не написал тип массива и предполагаемый (ожидаемый) размер.

В случае с типом arr() as string
произойдет перевод BSTR в ABSTR
и если массив будет не путым а большим тормоза обеспечены.

( В статье это кстати выдается за "фишку" но может я что то не понимаю )


Для определения BSTR** (strarr) используется специальная функция StrArrPtr! Никаких преобразований никуда :) Читай внимательно ;)
А для юзерских типов нуно использовать либо её аналог, переобъявленный для каждого юзерского типа, либо функцию AnyPtr - её мне там в комментариях написали :)
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

codemaster
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 604
Зарегистрирован: 13.02.2004 (Пт) 13:35

Сообщение codemaster » 04.10.2004 (Пн) 23:50

To "GSerg"

Итак тестируем вообщем безобидный код.
(Массив инициализирован!!!! )
Код: Выделить всё
Option Explicit

Private Declare Function GetMem4 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) _
As Long

Public Function StrArrPtr(arr() As String, Optional ByVal IgnoreMe As Long = 0) As Long
GetMem4 VarPtr(IgnoreMe) - 4, VarPtr(StrArrPtr)
End Function

Private Sub Command1_Click()
On Error Resume Next
Const CONST_ARR_SIZE As Long = 100000
Dim arr() As String
Dim laPtr As Long, lSize As Long
'
ReDim arr(CONST_ARR_SIZE) As String
'
laPtr = StrArrPtr(arr())
'
lSize = UBound(arr())

'
Debug.Print lSize, laPtr
'
End Sub


Performans поражает воображение см. архив.
Вложения
perf.zip
(44.46 Кб) Скачиваний: 24

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 05.10.2004 (Вт) 9:14

Судя по всему, это квантовый эффект :)
Факт наблюдения меняет поведение наблюдаемого объекта :)

Вот тело функции GetMem4:
Код: Выделить всё
mov eax, [esp+4]
mov ecx, [esp+8]
mov eax, [eax]
mov [ecx], eax
xor eax, eax
ret 8


Вот тело функции VarPtr:
Код: Выделить всё
mov eax, [esp+4]
ret 4



Укажи мне место, которое тормозит :)

ЗЫ: у меня не тормозит.
ЗЗЫ: от размера массива это не зависит вообще.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 05.10.2004 (Вт) 10:29

Я тут попробовал на эту тему, получилось две функции:

Код: Выделить всё
Public Function UboundArray(ArrayName As Variant, Optional Dimension As Integer = 1) As Long
    Dim d As Long
   
    d = GetArrayDimensions(ArrayName)
    If Dimension < 1 Or Dimension > d Then
        UboundArray = -1
    Else
        UboundArray = UBound(ArrayName, Dimension)
    End If
End Function

Public Function GetArrayDimensions(arr As Variant) As Integer
    Dim a As Long, b As Long
   
    CopyMemory b, ByVal VarPtr(arr) + 8, ByVal 4
    CopyMemory a, ByVal b, ByVal 4
    If a Then CopyMemory GetArrayDimensions, ByVal a, 2
End Function


GetArrayDimensions - возвращает размерность массива или 0 если массив не инициализирован.

UboundArray - возвращает кол-во элементов в указанной размерности массива или -1 если данная размерность не инициализирована.

То есть UboundArray неинициализированного массива вернет -1.

Как оно - сойдет?
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 05.10.2004 (Вт) 10:37

В общем чуть подчищенные функции:

Код: Выделить всё
Public Function UboundArray(ArrayName As Variant, Optional Dimension As Integer = 1) As Long
    If Dimension < 1 Or Dimension > GetArrayDimensions(ArrayName) Then
        UboundArray = -1
    Else
        UboundArray = UBound(ArrayName, Dimension)
    End If
End Function

Public Function GetArrayDimensions(arr As Variant) As Integer
    Dim a As Long

    CopyMemory a, ByVal VarPtr(arr) + 8, 4
    CopyMemory a, ByVal a, 4
    If a Then CopyMemory GetArrayDimensions, ByVal a, 2
End Function
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 05.10.2004 (Вт) 21:20

GSerg писал(а):Укажи мне место, которое тормозит :)

Тормозит, безусловно, вызов по Declare. Посмотри код DllFunctionCall (с названием могу врать) и ужаснись. У меня даже протрейсить её до конца терпения никогда не хватало.

Вот за этим-то и нужны TLB.
Изображение

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 05.10.2004 (Вт) 21:29

Это да...
Но я смотрел, как в exe реализованы вызовы getmem4 - они вообще идут как внутренние вызовы части exe, очень быстро.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: Yandex-бот и гости: 2

    TopList