![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как вставить элемент внутрь массива рекордов ? [D7]
Кто---то © (2004-11-15 01:40:00)Задумал написать функцию, которая бы вставляла элементы в массивы ЛЮБЫХ рекордов, но запнулся на том, как её озаглавить :
function InsertRec(anArray : array of ... ; Index : Integer): Boolean;
array of что ? array of record не получается. А как быть ? Мне же надо, чтобы не под какую то конретную рекорду, а чтобы универсально было. Как же написать тогда ?
Когда мы пишем :
function InsertRec(var anArray : array of ...
Мы разве не просто ссылку на массив передаём ? И если ссылку, то какая Дельфи разница на массив чего ведёт эта ссылка ?
А если передаём не только ссылку, то что именно ещё передаём ?
Подробности см в теме :
http://www.delphimaster.ru/cgi-bin/forum.pl?id=1100211902&n=0
Если тема закрыта потому, что этот вопрос слишком сложен для мастеров - то так и скажите, чтобы я зря не спрашивал. Всего не знает никто, кроме Бога, ничего в этом постыдного нет.
ЮЮ (2004-11-16 04:43:00) [1]для работы с массивами разных рекордов нужны будут свои типы.
var параметром может быть именно этот тип, а не array of T<SomeRecord>.
Для чего это в Unit Types эти типы, если бы всё так было просто?
type
TIntegerDynArray = array of Integer;
TCardinalDynArray = array of Cardinal;
TWordDynArray = array of Word;
TSmallIntDynArray = array of SmallInt;
TByteDynArray = array of Byte;
TShortIntDynArray = array of ShortInt;
TInt64DynArray = array of Int64;
TLongWordDynArray = array of LongWord;
TSingleDynArray = array of Single;
TDoubleDynArray = array of Double;
TBooleanDynArray = array of Boolean;
TStringDynArray = array of string;
TWideStringDynArray = array of WideString;
Ешё раз повторюсь, универсальный список любых рекордов - это TList, т.е. список указателей, которые, в свою очередь, указывают на участок памяти произвольного типа.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TMyRecord = record
a: integer;
b: string;
end;
PMyRecord = ^TMyRecord;
TMyRecordDynArray = array of TMyRecord;
TForm1 = class(TForm)
btnAddToList: TButton;
procedure FormCreate(Sender: TObject);
procedure btnAddToListClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
{ Private declarations }
FList: TList;
FDynArray: TMyRecordDynArray;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
function InsertRecInList(AList: TList; ANewRec: pointer; Index : Integer): boolean;
begin
// в этом случае InsertRecInList "универсальна", но для доступа к рекордам
// (в том числк для освобождения памяти) требуется приведение к реальному типу
Result := (Index >= 0) and (Index <= AList.Count);
if not Result then exit;
AList.Insert(Index, ANewRec);
end;
function AddRecInMyRecordDinArray(var ADynArray: TMyRecordDynArray; ARecord: TMyRecord): boolean;
begin
// в этом случае для каждого типа динамического массива запискей
// нужна будет своя процедура для манипуляции элементами массива, но пропадает
// необходимость контролировать занимаеиую сассивом память
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
FList := TList.Create;
end;
procedure TForm1.btnAddToListClick(Sender: TObject);
var
myRec: PMyRecord;
begin
New(myRec);
InsertRecInList(FList, myRec, 0);
Caption := IntToStr(FList.Count);
end;
procedure TForm1.FormDestroy(Sender: TObject);
var
i: integer;
myRec: PMyRecord;
begin
for i := 0 to FList.Count - 1 do begin
myRec := FList.Items[i];
dispose(myRec);
end;
end;
end.
Кто---то (2004-11-16 03:23:00) [2]
> ЮЮ © (15.11.04 08:11) [16]
> Type
> TSomeArray: array of <SomeType>
>
> function InsertRec(var Array : TSomeArray; Index : Integer):
> Boolean;
Что такое СамТип ? И какой он ?
Если я эту функцию хочу использовать для работы с массивами разных рекордов, то какой СамТип писать ? Или его можно как-то динамически менять ?
grig_p (2004-11-15 10:35:00) [3]Советую отказаться от массивов и использовать TObjectList. А вместо записей использовать классы.
TMyRec = class
...
описание полей
...
end;
только перед использованием класс нужно предварительно создать, удаление класса обеспечивает исключение из списка TObjectList (см. хелп по нему).
KilkennyCat (2004-11-15 10:20:00) [4]
> Verg © (15.11.04 10:12) [22]
ну разумеется. Однако, я вовсе не подразумевал использование стандартных функций. Естественно, что все придется реализовывать самому.
Verg (2004-11-15 10:12:00) [5]
> 17] KilkennyCat © (15.11.04 09:34)
>
> > Verg © (15.11.04 07:38) [14]
>
>
> возможно, глупость скажу... а если рассматривать массив,
> как область памяти, элемент массива аналогично, то разве
> мы что-либо нарушим в структуре, если одну область к памяти
> прибавим к другой? И важна ли нам в данном случае структура?
> Я к сожалению, не силен в истинной реализации работы памяти,
> все время представляю ее чем-то вроде файла...
Да как угодно.
Но здесь-то, раз уж применяются SetLength и Length, то речь шла о такой структуре как "динамический массив" - структура, поддерживаемая компилятором. Живет эта структура по своим правилам и нарушать эти правила компилер не позволит, т.к. он обязан выполнять корректно то, о чем заявляет в своих возможностях. Вот и все.
KilkennyCat (2004-11-15 09:57:00) [6]
> ЮЮ © (15.11.04 09:53) [20]
стоп... тип же известен. как я понял, имеется ввиду проблема создания процедуры, для которой типы неизвестны, но не для всей программы в целом. и если мы передаем ей данные о том, где хранится массив, где хранится будущий элемент, то можем ли мы слепить их?
ЮЮ (2004-11-15 09:53:00) [7]Как, если тип не известен? Зачем, если синтаксис Delphi все равно не позволит написать и использоваь такую функцию
KilkennyCat (2004-11-15 09:45:00) [8]
> ЮЮ © (15.11.04 09:38) [18]
разве это невозможно узнать?
ЮЮ (2004-11-15 09:38:00) [9]>KilkennyCat © (15.11.04 09:34) [17]
И колько памяти занимает элемент массива неизвестного типа?
KilkennyCat (2004-11-15 09:34:00) [10]
> Verg © (15.11.04 07:38) [14]
возможно, глупость скажу... а если рассматривать массив, как область памяти, элемент массива аналогично, то разве мы что-либо нарушим в структуре, если одну область к памяти прибавим к другой? И важна ли нам в данном случае структура?
Я к сожалению, не силен в истинной реализации работы памяти, все время представляю ее чем-то вроде файла...
ЮЮ (2004-11-15 08:11:00) [11]Type
TSomeArray: array of <SomeType>
function InsertRec( varArray : TSomeArray; Index : Integer): Boolean;
Кто---то (2004-11-15 07:53:00) [12]
> Verg © (15.11.04 07:38) [14]
> Я вроде тебе ясно сказал - невозможно работать с динамическим
> массивом не указав явно типа хранящихся в нем элементов.
Пусть указав.
В постинге [2] есть функция. Вы можете её передалать так, чтобы она заработала ?
Verg (2004-11-15 07:38:00) [13]
> А какой ? Или какое тут решение самое простое ?
Решение чего? Тут - это где?
Я вроде тебе ясно сказал - невозможно работать с динамическим массивом не указав явно типа хранящихся в нем элементов.
Кто---то (2004-11-15 07:01:00) [14]
> Verg © (15.11.04 06:22) [12]
> Т.о. процесс вставки/удаления элементов из такого массива
> может быть намного сложней, чем простой realloc и move...
А какой ? Или какое тут решение самое простое ?
Verg (2004-11-15 06:22:00) [15]
> Дело за малым. Угадать слово. Или несколько. :) Как бы ты
> решил этот кроссворд ?
Никак. По крайней мере пока.
> Мы разве не просто ссылку на массив передаём ? И если ссылку,
> то какая Дельфи разница на массив чего ведёт эта ссылка
> ?
Да, формально передается ссылка. Но информация о типе хранимых элементов там те лежит. Там есть только счетчик ссылок и длина массива (не размер в байтах, а сколько элементов).
Например, дин. массив вообще может быть равен nil, что означает пустой массив (length = 0).
Информацию же о типе хранимых в массиве элементах компилеру нужно знать явно.
Зная только pointer равный дин. массиву узнать тип хранимого элемента невозможно.
А тип нужно знать обязательно, т.к. это может быть и дин. массив и рекорд, содержащий строки, дин. массивы, интерфейсы и проч. нескалярные структуры. Т.о. процесс вставки/удаления элементов из такого массива может быть намного сложней, чем простой realloc и move...
Кто---то (2004-11-15 04:15:00) [16]
> dhdd (15.11.04 04:02) [10]
> Ну и смещай его через move:
> всё копируй (move) в новый массив (заново GetMem+1).
> с 3 до 11 копируй по индексу +1 и вставляй " новый рекорд
> на место третьего".
Можно пример кода ?
dhdd (2004-11-15 04:02:00) [17]Ну и смещай его через move:
всё копируй (move) в новый массив (заново GetMem+1).
с 3 до 11 копируй по индексу +1 и вставляй " новый рекорд на место третьего".
Кто---то (2004-11-15 03:45:00) [18]
> dhdd (15.11.04 03:25) [8]
> >Кто---то: массив надо раздвинуть
> Честно сказать - не понял.
Ну скажем массив из 10 рекордов. Чтобы вставить новый рекорд на место третьего, нужно увеличить количество рекордов до 11 и сдвинуть все начиная с третьего, чтобы освободить место куда вставить новый рекорд.
dhdd (2004-11-15 03:25:00) [19]>Кто---то: массив надо раздвинуть
Честно сказать - не понял.
Кто---то (2004-11-15 03:10:00) [20]
> dhdd (15.11.04 02:45) [5]
> function InsertRec
> (anArray,rec:pointer;index,recsize:integer):Boolean;
> В массив по адресу anArray со смещением index*recsize помещаем
> содержимое rec размером recsize: дальше по ассемблеру для
> оптима.
Честно сказать - не понял.
Прежде чем вставлять что-либо, массив надо раздвинуть в определённой точке. Вот мы и пытаемся.
> GuAV © (15.11.04 02:45) [6]
> О чём вообще речь ?
> если о type TRecord=class ..., как в той ветке то реализовать
> в принципе можно.
Есть массив рекордов причём тут классы ? Для чего эти переделки и навороты на ровном месте ?