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/