OberonCore https://forum.oberoncore.ru/ |
|
Динамический массив произвольных записей https://forum.oberoncore.ru/viewtopic.php?f=2&t=533 |
Страница 1 из 1 |
Автор: | Пётр Кушнир [ Понедельник, 25 Июнь, 2007 21:56 ] |
Заголовок сообщения: | Динамический массив произвольных записей |
Здраствуйте. Появилась необходимость создать динамический массив из произвольных записей. Т.е. тип записи не известен на момент написания кода. Например: Код: TYPE
Queue = POINTER TO ANYREC; Array = POINTER TO ARRAY OF Queue; Даже не представляю с чего начать, но почитал документацию к модулю MtMem, думаю, надо двигаться в этом направлении. Может у кого то есть готовые решения, или что-то похожее. Гдавное - результат. |
Автор: | Илья Ермаков [ Понедельник, 25 Июнь, 2007 22:28 ] |
Заголовок сообщения: | |
Вы совершенно правильно написали. Только вместо POINTER TO ANYREC можно использовать ANYPTR, что то же самое. Т.е. Array = POINTER TO ARRAY OF ANYPTR. Для динамической перемены длины можно использовать SetLength. Он есть не только в Mt, он продублирован в модуле Mem Service Pack 4.01. Проверку типа можно осуществлять стандартными способами - через IS, WITH. При необходимости можно и метапрограммирование задействовать (Meta, Services). |
Автор: | Пётр Кушнир [ Четверг, 28 Июнь, 2007 15:58 ] |
Заголовок сообщения: | |
А как тогда выделить память под элемент массива? Код: MODULE RefDoc;
IMPORT Meta, MtMem; TYPE Data = RECORD id : INTEGER; END; VAR data : Data; queue : POINTER TO ARRAY OF ANYPTR; PROCEDURE Do*; BEGIN NEW(queue,5); queue[0] := data; [так нельзя] NEW(queue[0]) [так тем более нельзя] END Do; END RefDoc. Тип элемента массива определить можно, но что-то никак не соображу, как быть с запретом на NEW для ANYPTR. |
Автор: | Иван Горячев [ Четверг, 28 Июнь, 2007 16:11 ] |
Заголовок сообщения: | |
Petryxa писал(а): Тип элемента массива определить можно, но что-то никак не соображу, как быть с запретом на NEW для ANYPTR.
Код: TYPE
Rec = POINTER TO RECORD val :REAL END; ... VAR p : Rec; BEGIN NEW(p); queue[0] := p; |
Автор: | Иван Кузьмицкий [ Четверг, 28 Июнь, 2007 16:36 ] |
Заголовок сообщения: | |
Petryxa писал(а): А как тогда выделить память под элемент массива?
... Тип элемента массива определить можно, но что-то никак не соображу, как быть с запретом на NEW для ANYPTR. А если так: Код: MODULE RefDoc;
IMPORT Dialog, Meta, MtMem; TYPE Data = POINTER TO RECORD id : INTEGER; END; VAR data : Data; queue : POINTER TO ARRAY OF ANYPTR; PROCEDURE Do*; BEGIN NEW(queue,5); NEW(data); data.id := 1000; queue[0] := data; END Do; END RefDoc. То есть, заводим указатель на запись, инициализируем его и потом просто присваиваем. |
Автор: | Александр Ильин [ Четверг, 28 Июнь, 2007 19:25 ] |
Заголовок сообщения: | |
Petryxa писал(а): Код: queue[0] := data; [так нельзя] Так нельзя только потому, что тип Data объявлен как RECORD, а не POINTER TO RECORD. А то понакатали исходников в ответ... |
Автор: | Иван Кузьмицкий [ Пятница, 29 Июнь, 2007 09:38 ] |
Заголовок сообщения: | |
Гм. С передачей в произвольную очередь понятно. А вот как обратно, неужели придётся делать приведение типов? Код: ...
NEW(queue,5); NEW(data); data.id := 1000; queue[0] := data; (*туда*) data := queue[0]; (*обратно компилятор не пропускает, есес-но*) |
Автор: | Александр Ильин [ Пятница, 29 Июнь, 2007 09:54 ] |
Заголовок сообщения: | |
Иван А. Кузьмицкий писал(а): Гм. С передачей в произвольную очередь понятно. А вот как обратно, неужели придётся делать приведение типов?
Конечно! WITH и IS вам помогут. Можно делать и приведение без предварительной проверки, но в случае несоответствия типов получите trap, так что безопасность не пострадает: просто так что угодно к чему угодно не приведете. |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |