Как пройти циклом по массиву? :-)

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

Как пройти циклом по массиву? :-)

Сообщение tyomitch » 12.07.2006 (Ср) 18:13

На VB это просто:
Код: Выделить всё
Sub DoSomething(ByVal v As Variant)
...
End Sub

Sub Iterate(ByVal w As Variant)
Debug.Assert IsArray(w)
Dim v As Variant
For Each v In w: DoSomething v: Next
End Sub

DoSomething уже написана на "обычном языке" (не мной). Мне надо написать Iterate на том же языке.

w -- это массив неизвестного заранее типа. Iterate должна пройти по нему в цикле, и каждый элемент перед вызовом привести к Variant.

Тут целых две проблемы: как проходить в цикле по массиву неизвестного заранее типа, и как приводить объект неизвестного заранее типа к Variant.

Посоветуете что-нибудь?
Последний раз редактировалось tyomitch 12.07.2006 (Ср) 20:08, всего редактировалось 1 раз.
Изображение

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 12.07.2006 (Ср) 19:23

Не могу понять в чём же проблема этих двух проблем, а также что за
"обычный язык". Это типа как в рекламах "Обычный порошок" ?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Сообщение tyomitch » 12.07.2006 (Ср) 19:31

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

Approximator
Постоялец
Постоялец
 
Сообщения: 572
Зарегистрирован: 26.06.2004 (Сб) 3:10

Сообщение Approximator » 12.07.2006 (Ср) 19:43

tyomitch писал(а):"обычный язык" -- это любой без встроенной поддержки COM.
Если можешь помочь, помоги. Только я уже скоро своими силами, думаю, дойду...

Конечно дойдёшь. Единственный прикол с Variant'ом, что это структура с поинтером на данные. Сейчас (ещё недели полторы) нахожусь за компом, где не установлена VS. Есть самописная асмовская библа (native dll) для тонкой работы с массивами (операции со всевозможной итерацией), в т.ч. с данными типа Variant. Если не сильно горит (вернусь за комп, где всё есть только через полторы недели) могу помочь. Если горит, проще разобраться самому. Кстати, у GSerg'а есть статья про массивы и работу с ними.
С уважением, Approximator.

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

Сообщение tyomitch » 12.07.2006 (Ср) 22:13

(То, что было в этом посте написано раньше, -- неправда)

Значит, на самом деле msvbvm копирует (SafeArrayCopy) лежащий в w массив во временный SAFEARRAY(VARIANT), и потом циклит уже по нему, без проблем. Имхо неожиданное решение: а если бы у меня в w был гигабайтный массив?
Изображение

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 12.07.2006 (Ср) 22:22

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

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

Сообщение tyomitch » 13.07.2006 (Чт) 19:52

ANDLL, ты не прав. Положим, у меня была задача, которую мне героическими усилиями удалось запихнуть в гиг памяти. (Была, кстати: про ферзей с фиберами.) И значит, VB у меня отъест ещё вчетверо больше только затем, чтобы пройти в цикле по массиву? Так нечестно!

------------------------------

К слову об интересных эффектах с вариантами. От этого кода IDE впадает в анабиоз: не работает, но и не помирает :-)

Код: Выделить всё
Option Explicit

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

Sub Main()
Dim v As Variant
CopyMemory v, &H400C, 2
CopyMemory ByVal VarPtr(v) + 8, VarPtr(v), 4
MsgBox v
End Sub
Изображение

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

Сообщение tyomitch » 13.07.2006 (Чт) 20:21

А вот, собственно, ответ на вопрос топика: цикл по массиву без создания временной вариантной копии.

Синтаксис VB использован в чисто иллюстративных целях; но этот код проверен и работает.
Код: Выделить всё
Option Explicit

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

Sub DoSomething(ByVal v As Variant)
Debug.Print v
End Sub

Sub Iterate(ByVal w As Variant)
Debug.Assert IsArray(w)
Dim v As Variant, i As Long, psa As Long, c As Long, pdata As Long
CopyMemory psa, ByVal VarPtr(w) + 8, 4
CopyMemory c, ByVal psa, 2
Debug.Assert c = 1 'одномерность
CopyMemory c, ByVal psa + 4, 4
CopyMemory pdata, ByVal psa + 12, 4
CopyMemory v, (VarType(w) And Not vbArray) Or &H4000, 2
For i = LBound(w) To UBound(w)
    CopyMemory ByVal VarPtr(v) + 8, pdata, 4
    DoSomething v
    pdata = pdata + c
Next
CopyMemory v, Empty, 16
End Sub

Sub Main()
Dim b() As Byte: b = "Hello!"
Iterate b()
Dim i() As Long: ReDim i(3)
i(1) = 2: i(3) = 4
Iterate i()
Dim s() As String: ReDim s(1)
s(0) = True: s(1) = False
Iterate s()
Dim w() As Variant: ReDim w(1)
w(0) = Null: w(1) = CVErr(123)
Iterate w()
End Sub
Изображение

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

Сообщение tyomitch » 14.07.2006 (Пт) 12:19

Хакер писал(а):Не могу понять в чём же проблема этих двух проблем, а также что за
"обычный язык". Это типа как в рекламах "Обычный порошок" ?

Только сейчас обратил внимание, что Хакера постоянно заносит в одну и ту же сторону: порошок и тому подобное :lol:
Изображение

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

Сообщение tyomitch » 14.07.2006 (Пт) 16:36

Следующая проблема -- как сделать, чтобы DoSomething могла не только читать из v, но и писать назад...
Чего-то в голову ничего не идёт. Может, Approximator даст совет?
Так как есть сейчас -- она перезаписывает мой вариант новым, а не изменяет содержимое по ссылке.
Изображение


Вернуться в Народный треп

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

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 102

    TopList  
cron