Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Вниз

Вариантный массив   Найти похожие ветки 

 
gdaujk ©   (2006-10-12 10:20) [0]

Доброго времени суток, уважаемые мастера.

У меня к вам следующий вопрос. Есть пустой, но уже инициализированный с помощью VarArrayCreate, двумерный вариантный массив данных типа varDouble;

V := VarArrayCreate([0, RowCount – 1, 0, ColCount - 1], varDouble);

Ещё есть обычный массив A, тоже двумерный, с тем же числом элементов. Мне необходимо скопировать массив A  в вариантный массив V. Я делаю так:

for I := 0 to (RowCount - 1) do
 for J := 0 to (ColCount - 1) do
   V[I, J] :=  A[I, J];

Всё работает корректно. НО. Прочитал, что это операция заведомо очень длительная, ибо каждый раз при присвоении значения элементу V[I, J] происходит определение типа и проверка на совместимость. Предлагается подобный код:

pV := VarArrayLock(V);
Move(A, pV^, RowCount * ColCount * SizeOf(Double));
VarArrayUnlock(V);


Только этот код не работает, т. е. V не заполняется данными из A. Подскажите, что я делаю не так, и вообще, как скопировать A в V без  поочерёдного приравнивания их элементов в цикле?


 
Palladin ©   (2006-10-12 10:38) [1]


> gdaujk ©

массив A как объявлен?


 
Leonid Troyanovsky ©   (2006-10-12 14:07) [2]


> gdaujk ©   (12.10.06 10:20)  

> из A. Подскажите, что я делаю не так, и вообще, как скопировать
> A в V без  поочерёдного приравнивания их элементов в цикле?


Взгляни на пример с одномерным массивом

http://groups.google.com/group/fido7.ru.delphi/msg/39bb6f8532669ca2

--
Regards, LVT.


 
Сергей М. ©   (2006-10-12 15:25) [3]


> gdaujk ©   (12.10.06 10:20)


Если переменная A имеет указательный тип, то

Move(A^, .....);


 
gdaujk ©   (2006-10-12 18:03) [4]

>> Leonid Troyanovsky ©   (12.10.06 14:07) [2]

Спасибо за пример. Попробовал сделать нечто подобное для двумерного массива:

TTwoDemArr = array[0..0] of array[0..0] of Double;
PTwoDemArr = ^TTwoDemArr;

procedure TForm1.Button1Click(Sender: TObject);
var
 V: Variant;
 A, pV: PTwoDemArr;
 I, J: Integer;
begin
 GetMem(A, 50 * SizeOf(Double));
 for I := 0 to 9 do
   for J := 0 to 4 do
     A[I, J] := J * 10 + I;
 V := VarArrayCreate([0, 4, 0, 9], varDouble);
 pV := VarArrayLock(V);
 try
   Move(A^, pV^, 50 * SizeOf(Double));
 finally
   VarArrayUnlock(V);
 end;
 Label1.Caption := FloatToStr(V[0,1]);
 FreeMem(A);
end;


В результате выполнения сего кода и последующего просмотра элементов V я пришёл к следующему выводу: копируется только первая строчка массива A – 0, 1, 2, … , 9 – а остальное содержимое -  нет.

Замечу, что в описании функции VarArrayLock сказано: the dimensions of the returned array pointer are reversed from the dimensions of the variant array, то есть матрица превращается в обратную (может это называется по-другому, я плохо знаю математику :-)

>> Palladin ©   (12.10.06 10:38) [1]

Я по-всякому объявлял: и как указатель (Pointer), и как динамический двумерный массив (array of array of Double), и как описано выше. Мне кажется загвоздка не в этом…

PS: Leonid Troyanovsky, может ещё объясните вкратце суть конструкции array[0..0]. Помнится, здесь  я раз читал типик на эту тему, но в память ничего не осталось :-)


 
Leonid Troyanovsky ©   (2006-10-12 18:54) [5]


> gdaujk ©   (12.10.06 18:03) [4]


> Спасибо за пример. Попробовал сделать нечто подобное для
> двумерного массива:

> TTwoDemArr = array[0..0] of array[0..0] of Double;

Не, это не совсем то. Если мы собираемся заполнить
вариант значениями массива (как потоком байтов), то
мы должны конкретно указать размерность:

 TTwoDemArr = array [0..4, 0..9] of Extended;

и использовать указатель на оную структуру при чтении
этого "потока". Т.е., "принимающая" строна должна
использовать тоже описание массива, что и передающая.

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

См. также

http://groups.google.com/group/fido7.ru.delphi/msg/7ede8862b5ecd8b5

> PS: Leonid Troyanovsky, может ещё объясните вкратце суть
> конструкции array[0..0]. Помнится, здесь  я раз читал типик
> на эту тему, но в память ничего не осталось :-)

Это не совсем верная запись.
Т.е., по-взрослому, для  динамически аллоцируемых массивов
положено примерно так:

TArrayData = array [0..MAXLONGINT div 16] of Extended;

для того, чтобы можно было контролировать выход за
границу массива.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2006-10-12 18:59) [6]


> Leonid Troyanovsky ©   (12.10.06 18:54) [5]

>  TTwoDemArr = array [0..4, 0..9] of Extended;

array of ... Double;
Sorry.

--
Regards, LVT.


 
gdaujk ©   (2006-10-12 20:37) [7]

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

array [0..MAXLONGINT div 16]

Привожу работающий код:

procedure TForm1.Button2Click(Sender: TObject);
var
 V: Variant;
 pV, A, p: PDouble;
 I, J: Integer;
begin
 GetMem(A, 50 * SizeOf(Double));
 p := A;
 for I := 0 to 9 do
   for J := 0 to 4 do
   begin
     p^ := J * 10 + I;
     Inc(p);
   end;
 V := VarArrayCreate([0, 4, 0, 9], varDouble);
 pV := VarArrayLock(V);
 try
   Move(A^, pV^, 50 * SizeOf(Double));
 finally
   VarArrayUnlock(V);
 end;
 Label1.Caption := VarToStr(V[2,9]);
 FreeMem(A);
end;


Товарищи!!! Дружно скажем "Нет!" динамическим массивам!!! :-)

PS: Leonid Troyanovsky, благодарю за идею о преобразования многомерных массивов к одномерным.

PPS: если в приведённом выше коде кто-то заметит существенные недостатки, прошу обязательно написать о них.



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.039 c
2-1163068156
pkm
2006-11-09 13:29
2006.11.26
Работа с мемо.


3-1159162825
e_u_
2006-09-25 09:40
2006.11.26
создание базы данных


2-1163056398
_ttl
2006-11-09 10:13
2006.11.26
TMemo


15-1162605071
naxellar
2006-11-04 04:51
2006.11.26
Блокировка клавиатуры и мыши в WinXP


4-1152879465
Acidlex
2006-07-14 16:17
2006.11.26
Эмуляция нажатия клавиш в чужом окне





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский