Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как вставить элемент внутрь массива рекордов ? [D7]


Страницы:   1 2

Кто---то ©   (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 ..., как в той ветке то реализовать
> в принципе можно.

Есть массив рекордов причём тут классы ? Для чего эти переделки и навороты на ровном месте ?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо