![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Динамические массивы
cyber-pilot © (2009-04-24 15:17:00)Я использую динамические массивы и часто бывает нужно увеличить его на один элемент и занести в последний элемент какие-нибудь данные. Я делаю это примерно так:
type
TRec = record
a: Integer;
b: Char;
end;
TRecList = array of TRec;
var
vRecList: TRecList;
vLen: Integer;
begin
//...
vLen := Length(vRecList);
SetLength(vRecList, vLen + 1);
vRecList[vLen].a := 1;
vRecList[vLen].b := 'c';
//...
end;
Можно ли сделать функцию, которая инкрементила бы любой динамический массив и возвращала номер последнего элемента, а лучше сам этот элемент?
жж (2009-04-24 19:52:00) [1]Предполагаю, что автор ветки не в курсе существования TList'а, который и решил бы проблему
cyber-pilot (2009-04-24 17:32:00) [2]Всем спасибо!
Юрий Зотов (2009-04-24 17:21:00) [3]Можно извратиться примерно так (массив должен быть packed):
function IncDinArr(Arr: Pointer; Info: PTypeInfo): Pointer;
begin
... // См. [10]
// Теперь, зная адрес массива, его длину Len и размер элемента Size,
// вычисляем адрес последнего элемента:
Result = Pointer((Cardinal(Arr) + Len*Size))
end;
===================
// И остается только привести тип указателя:
with PRec(IncDinArr(vRecList, ...))^ do
begin
a := 1;
b := 'c';
end;
Sapersky (2009-04-24 17:14:00) [4]Можно ли сделать функцию, которая инкрементила бы любой динамический массив и возвращала номер последнего элемента, а лучше сам этот элемент?
Ну посмотри это (Arr_AddItem, на базе того же DynArraySetLength):
http://sapersky.narod.ru/files/Arrays.rar
Хотя мне самому оно не очень нравится, по 5 параметров в функцию загонять - громоздко... но если делать для массива некую обёрточную структуру (чтобы хранить TypeInfo/Count), пропадёт возможность обращения к элементам без тайпкаста.
В D2009 можно ещё попробовать дженерики.
cyber-pilot (2009-04-24 17:14:00) [5]
> Юрий Зотов © (24.04.09 17:08) [18]
> Увеличить длину можно. Но результат КАКОГО типа должна возвращать
> такая функция? Вот этот самый Ваш with - он с ЧЕМ работать
> должен? И как это объяснить компилятору?
Да, собственно, это я и хотел узнать.
Юрий Зотов (2009-04-24 17:08:00) [6]> cyber-pilot (24.04.09 17:04) [17]
> Смысл был в том, чтобы это работало для любого динамического массива.
Увеличить длину можно. Но результат КАКОГО типа должна возвращать такая функция? Вот этот самый Ваш with - он с ЧЕМ работать должен? И как это объяснить компилятору?
cyber-pilot (2009-04-24 17:04:00) [7]
> Юрий Зотов © (24.04.09 16:52) [15]
Смысл был в том, чтобы это работало для любого динамического массива.
> Denis__ © (24.04.09 16:55) [16]
Ты смотришь ввысь, а я вширь :)
Denis__ (2009-04-24 16:55:00) [8]Код не сократился... там где было 4 строки, теперь 5. В чем прикол этой затеи?
Юрий Зотов (2009-04-24 16:52:00) [9]function IncDinArr(RecList: TRecList): TRec;
begin
SetLength(RecList, Length(RecList) + 1);
Result = RecList[High(RecList)]
end;
===================
with IncDinArr(vRecList) do
begin
a := 1;
b := 'c';
end;
cyber-pilot (2009-04-24 16:37:00) [10]
> MBo © (24.04.09 16:04) [11]
> А зачем все это нужно?
Это нужно для сокращения кода. Вместо этого:
type
TRec = record
a: Integer;
b: Char;
end;
TRecList = array of TRec;
var
vRecList: TRecList;
vLen: Integer;
begin
//...
vLen := Length(vRecList);
SetLength(vRecList, vLen + 1);
vRecList[vLen].a := 1;
vRecList[vLen].b := 'c';
//...
end;
писать вот так:
type
TRec = record
a: Integer;
b: Char;
end;
TRecList = array of TRec;
var
vRecList: TRecList;
begin
//...
with IncDinArr(vRecList) do
begin
a := 1;
b := 'c';
end;
//...
end;
Мне кажется так будет удобнее. Хотя может быть я и извращенец :)
MBo (2009-04-24 16:20:00) [11]>Можно сказать - вообще никакого)
Это я пытаюсь понять, что автор хочет, и какие он желает извлечь полезности :)
Например, желание возврата элемента массива, которому только что присвоили значение - тонкий изврат, imho
Сергей М. (2009-04-24 16:09:00) [12]
> удовольствие небольшое, однако.
Можно сказать - вообще никакого)
> TypeInfo(TIntArr)
Тип известен на этапе компиляции
MBo (2009-04-24 16:04:00) [13]А зачем все это нужно?
MBo (2009-04-24 16:03:00) [14]
type
TIntArr = array of Integer;
var
A: TIntArr;
L: integer;
begin
L := 5;
DynArraySetLength(Pointer(A), TypeInfo(TIntArr), 1, @L);
Caption := IntToStr(Length(A));
удовольствие небольшое, однако...
Сергей М. (2009-04-24 16:03:00) [15]
> функция должна вернуть именно элемент массива
Чтобы она чего-то тебе вернула, нужно чтобы в декларации ф-ции
function MyFunc(хрен знает что за массив): TТипРезультата;
Вот я и задаю вопрос - что ты собрался писать вместоTТипРезультата?
cyber-pilot (2009-04-24 15:59:00) [16]Видимо я не правильно выразился, функция должна вернуть именно элемент массива, просто не знаю как это правильно записать.
Сергей М. (2009-04-24 15:51:00) [17]Сначала тебе элемент вернуть надо, теперь тип элемента ..
Ты уж определись что тебе нужно - то ли элемент, то ли его тип) ..
cyber-pilot (2009-04-24 15:48:00) [18]
> MonoLife © (24.04.09 15:39) [4]
> >cyber-pilot
> а справку почитать на счет High() Low().. length() и т.
> п..?
Читал. Как это относится к теме моего вопроса?
cyber-pilot (2009-04-24 15:46:00) [19]
> Сергей М. © (24.04.09 15:36) [3]
> Можно, не нужно.
>
>
> > а лучше сам этот элемент
>
>
> Как ты это себе представляешь ?
> Что значит вернуть его элемент, если тип элементов массива
> заранее неизвестен ?
Я бы хотел примерно такую функцию:
function IncDinArr(массив; тип элемента массива): тип элемента массива;
MonoLife (2009-04-24 15:39:00) [20]>cyber-pilot
а справку почитать на счет High() Low().. length() и т.п..?