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

Вниз

Динамические массивы в Делфи 3   Найти похожие ветки 

 
ELKa   (2003-07-29 15:13) [0]

Только не смейтесь... Кто-нибудь пробовал скомпилировать такой вот кусочек кода в Делфи 3:
var a: array of integer;
begin
end;

У меня не получилось. Выдается ошибка что ""[" expected but "of" found". Не помогает так же и создание

type tarray=array of integer;

Если кто знает как это лечится (не я а Делфи 3 + динамические массивы), то напишите,буду очень благодарна.

К теме: в хелпе по дин. массивам такой код нарисован и даже написано что он замечательно компилируется. Так же там присутствует красивая функция SetLength(array,length), которая якобы задает величину динамического массива, но при попытке ею воспользоваться у меня выскакивает следующее:

Incompatible types string and array.

Т.е. реально обрезается строка.

Люди, помогите... :(


 
MBo   (2003-07-29 15:16) [1]

в D3 нет динамических массивов, встроенных в язык в том виде, как в D4 и позднее.
При необходимости делается что-то подобное:
PIntArray=^TIntArray;
TIntArray=array[0..1000000] of Integer;

var P:PIntArray;
GetMem(P,100*SizeOf(Integer));
и работаем
P^[33]:=5;
и т.д.


 
ELKa   (2003-07-29 15:30) [2]

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

a: array[1..230] of integer;

и заполнить например только первые 2 его значения и передать его в функцию, то в функции размер этого массива будет считаться 230, а не 2. Из-за этого виснем и т.п...

Но все-равно спасибо - теперь хоть знаю что в Делфи 3 нет такого...



 
han_malign   (2003-07-29 15:37) [3]

>MBo © (29.07.03 15:16)
- а я в свое время(в институте) с вариантными массивами мучался, теперь бы? само собой? не стал бы, громоздко слишком, и былого страха перед GetMem давно уже не осталось... :)))
З.Ы. Но, все-таки не удержусь, и посоветую никогда не забывать про связку
GetMem(P,100*SizeOf(Integer)); FillChar(P ^,100*SizeOf(Integer),0);
параноей конечно отдает, но иногда бывает полезно(да и FreeMem сразу писать надо(в деструкторе или в конце процедуры, если массив локальный), а потом уже математику между ними писать))...
З.З.Ы. А иногда следует трезво оценивать необходимость динамического массива, и просто делать массив с запасом, если известно максимально возможное количество элементов - по скорости поэффективней будет.


 
han_malign   (2003-07-29 15:47) [4]

>ELKa (29.07.03 15:30)
- динамический массив, или все-таки открытый?
вызов Func([parama1,param2]) - должен пройти(хотя не уверен), а если количество элементов заранее не известно, надо со стеком мудрить, только лично я не знаю - длинна массива до указателя на него запихивается, или после, надо соглашения по передаче параметров почитать... Или формировать аля-динамический массив ручками, можно попробовать a[0]:=2; func(tarray((@a[1])^)); (длинна динамического массива/строки, лежит по смещению (а-4)), хотя не факт...


 
ELKa   (2003-07-29 15:56) [5]

Все это конечно хорошо, но как-раз вот этот лишний запас (бывает достаточно 10 элементов), вызывает глобальные ошибки и подвисание задачи...

К тому же, видимо Вы han_malign, не очень внимательно читали мой ответ MBo , потому что поняли бы из него, что я уже не решаю - использовать динамический массив или нет. Его УЖЕ используют. А мне надо как-то передать в функцию с дин. массивом динамический же массив, а не статический. Для большего понимания приведу пример:

Вызывается функция showReport(params: array of TvarRec) - это дано изначально. В ней используется функция high(params) чтобы определить количество элементов в этом массиве.

Так вот, вызывая функцию например так:
showReport(["а","f"])

high внутри нее покажет размер params равным 1 (номерация с ноля) и все работает замечательно, но если сделать так:

var a: array[1..30] of tvarrec;
begin
a[1].vtype:=vtpchar;
a[1].vpchar:=pchar("a");
a[2].vtype:=vtpchar;
a[2].vpchar:=pchar("f");

showReport(a);

то функция high внутри showReport выдаст размер массива param не 1, а 29. Всвязи с чем при последовательной обработке всех данных в param возникают ОГРОМНЫЕ проблемы (из-за заполненности его бредовыми значениями в т.ч.).

Посему мне была бы очень полезна возможность описать массив а не как
a:array[1..30] of tvarrrec

а как
a:array of tvarrec.

MBo популярно объяснил что Д3 так не работает...И на том спасибо.


 
han_malign   (2003-07-29 16:14) [6]

Процитирую "не очень внимательно читали мой ответ"...
Надо в отладчике, в CPU View, посмотреть как передается длинна массива для случая showReport(["а","f"]), затем переписать в ассемблерной вставке точно так-же вызов процедуры, за одним исключением, затолкав в стек нужню длинну, или сформировав структуру аналогичную динамическому массиву, так как это делает компилятор(не разбирался и не знаю какой из вариантов)...


 
MBo   (2003-07-29 16:20) [7]

>showReport(params: array of TvarRec)
Это не динамический массив, а, как han_malign и предположил - ОТКРЫТЫЙ параметр-массив.

>a:array[1..30] of tvarrrec
>high внутри showReport выдаст размер массива param не 1, а 29
все правильно! открытый массив нумеруется с нуля!

Если объявить
a:array[0..29] of tvarrrec;
то нумерация будет совпадать, но и без этого можно обойтись, просто учитывая при необходимости единичку, хотя часто абсолютное значение индекса не используется.



 
ELKa   (2003-07-29 16:28) [8]


> Если объявить
> a:array[0..29] of tvarrrec;
> то нумерация будет совпадать, но и без этого можно обойтись,
> просто учитывая при необходимости единичку, хотя часто абсолютное
> значение индекса не используется.


Ёлки...Тут ни при чем нумерация с ноля или с единицы. Я это прекрасно и раньше знала...

ДЕЛО В РАЗМЕРЕ МАССИВА. Если его описать как
a:array[1..30] of integer;
и заполнить a[1]:=1; a[2]:=2; и все, то high(a) бyдeт равно 29!!

А если массив описан как
a:array of integer;
и заполнить a[1]:=1; a[2]:=2; то high(a)=1; (что отрабатывает и на Д4 и на Д5, но не работает на Д3)

ВОТ В ЧЕМ ДЕЛО! Функция при первом варианте обрабатывает лишние 29 элементов массива, которых на самом деле нет. Соответственно выдаются бредовые результаты. Когда же используется второй вариант, то результат тот что нужно.



 
han_malign   (2003-07-29 16:28) [9]

а конкретно (использовал, для быстроты тип Char, но
это уже не принципияльно)

var aa: array[0..13]of TVarRec;
i,L: integer;
begin
L:=5;
for i:=0 to L do with aa[i] do begin
aa[i].VType:=vtChar;
Vchar:=Char(Byte("a")+i);
end;
asm
lea EAX,[aa]
mov EDX,L
call ShowReport
end;
..........................................
end;


 
ELKa   (2003-07-29 16:33) [10]

Вот за это

> asm
> lea EAX,[aa]
> mov EDX,L
> call ShowReport
> end;


уже большое спасибо :)
Только я привела пример не реальный (не та ситуация что у меня), у меня в вызываемой функции не один, а 4 параметра, первый из которых целого типа, остальные 3 открытые массивы. Что в этом случае следует дописать?


 
reonid   (2003-07-29 16:37) [11]

Попробуй использовать ф-я Slice - она
специально предназначена для установки длины при передаче открытых массивов:

showReport(Slice(params, ЧислоРеальноИспользуемыхЭлементов));


 
KDS   (2003-07-29 16:38) [12]

Динамические появились только в 4-ой версии Делфи
До этого я выкручивался типом Variant и Variant arrays
V: Variant;

...
V := VarArrayCreate([0,9], varInteger);


 
MBo   (2003-07-29 16:44) [13]

Дело в том, что компилятор знает на этапе компиляции длину стат. массива, и передает ее (-1) как high(params).
В D4 и выше динамический массив обрабатывается по другому, в runtime high получается.
В D3 можно сделать обертку, с помощью которой и удастся работать.


procedure showReport(params: array of Integer);
var
i:integer;
begin
for i:=0 to High(params) do
Form1.Memo1.Lines.Add(IntToStr(params[i]))
end;

procedure CallShowReport(var params; Count:Integer);
asm
dec edx
call showreport
end;

procedure TForm1.Button1Click(Sender: TObject);
var
a:array[1..30] of integer;
begin
a[1]:=1;
a[2]:=2;
CallShowReport(a,2);
end;


 
ELKa   (2003-07-29 16:47) [14]

reonid - Все, получилось :))) Все оказалось как всегда просто, огромнейшее Вам спасибо :) С меня пиво ;)



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

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

Наверх





Память: 0.49 MB
Время: 0.006 c
14-33327
Маратей
2003-07-25 10:55
2003.08.11
IExporer, Вызов окна


1-33119
zzet
2003-07-30 08:36
2003.08.11
Изменить внешний вид.


6-33236
napil
2003-06-01 04:14
2003.08.11
Потоковое AUDIO


14-33281
Axel
2003-07-23 18:13
2003.08.11
O !


1-33112
Nucl
2003-07-29 17:24
2003.08.11
Как клонировать компоненты на форме





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский