OberonCore
https://forum.oberoncore.ru/

Как написать обобщённый список на ББ.
https://forum.oberoncore.ru/viewtopic.php?f=35&t=4606
Страница 1 из 3

Автор:  Jordan [ Четверг, 07 Ноябрь, 2013 13:43 ]
Заголовок сообщения:  Как написать обобщённый список на ББ.

Как на языке КП написать обобщённый список? Или какие есть альтернативы? Если нужен список разных типов, возможно ли для этого применить расширенные записи?

Цель, есть список структур данных. button и checkbox, на с++ использую stl list, создаю два списка и работаю над ними отдельно. По мере сил, структуры будут добавляться.(В с++ переделал на vector указателей, смысл не меняется)

Как в КП избежать дублирования, кода списка? Возможно ли на КП объединить типы через аналог union в си? Расширенные записи и есть безопасный аналог си?

(модератор) ссылка на решение проблемы: viewtopic.php?p=84984#p84984

Автор:  Jordan [ Четверг, 07 Ноябрь, 2013 13:49 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Да ещё пояснение, не хотелось бы привязываться к ББ фишкам. Если возможно, по стандарту оберона 2. Что бы если всё же осилю эту задачу, была возможность компилировать на компиляторах языка oberon 2.

Автор:  Илья Ермаков [ Четверг, 07 Ноябрь, 2013 14:04 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Допустим, по принципам ещё Delphi-List.
Список указателей ANYPTR.

Чтобы не сували некорректные типы в список, можно при создании списка указывать имя типа (как строковый параметр), а процедуры Add, Insert и т.п. будут проверять через Meta.Item.Is - что объект имеет этот тип.

Автор:  Илья Ермаков [ Четверг, 07 Ноябрь, 2013 14:05 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Ах, да, в Обероне-2 нет ANYPTR.
Тогда потребуется базовый Object.

Автор:  Jordan [ Четверг, 07 Ноябрь, 2013 14:25 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Вот пример на паскале, более близком к КП.

type
PButton = ^TButton;
TButton = record
PosX : integer;
PosY : integer;
SizeX : integer;
SizeY : integer;
Name : string;
ReDraw: boolean;
Next : PButton;
end;

type
PCheckbox = ^TCheckbox;
TCheckbox = record
PosX : integer;
PosY : integer;
SizeX : integer;
SizeY : integer;
Value : bool;
ReDraw: boolean;
Next : PCheckbox;
end;

var
Table: PButton;


function Create(Name: string; PosX, PosY, SizeX, SizeY: integer): PButton;
var
P: PButton;
begin
New(P);
P^.PosX := PosX;
P^.PosY := PosY;
P^.SizeX := SizeX;
P^.SizeY := SizeY;
P^.Name := Name;
P^.ReDraw:= true;

P^.Next := Table;
Table := P;

Result := P;
end;

Как объединить в расширенную запись 2 записи?

Илья Ермаков писал(а):
Чтобы не сували некорректные типы в список, можно при создании списка указывать имя типа (как строковый параметр), а процедуры Add, Insert и т.п. будут проверять через Meta.Item.Is - что объект имеет этот тип.


Я не понял насчёт Meta.Item.Is. Моя идея заключается в том, что бы не возвращать указатель, а возвратить id. Тогда будет нельзя обратиться к полям записи.

Пример

function Create(Name: string; PosX, PosY, SizeX, SizeY: integer): integer;
var
P: PButton;
begin
New(P);
inc(Count); \\ по умолчанию count = -1
P^.Id := Count;
P^.PosX := PosX;
P^.PosY := PosY;
P^.SizeX := SizeX;
P^.SizeY := SizeY;
P^.Name := Name;
P^.ReDraw:= true;

P^.Next := Table;
Table := P;

Result := P^Id;
end;

Как обращаться к записи.

function FindId(Id: integer): Pbutton;
var
P: PButton;
begin
P := Table;
while (P <> NIL) and (P^.Id <> Id) do
begin
P := P^.Next;
end;

Result := p;
end;

function GetPosX(Id: integer)
var
P: PButton;
begin
P := FindId(Id);
Assert(P <> NIL);

Result := P^.PosX;
end;

Илья Ермаков писал(а):
Ах, да, в Обероне-2 нет ANYPTR.
Тогда потребуется базовый Object.


Как создать базовый объект в оберон 2. Как в object pascale?

Автор:  Jordan [ Четверг, 07 Ноябрь, 2013 14:38 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Ещё нужно добавлять объекты в очередь. Нужна ещё и обобщённая очередь. Если по числу объектов писать структуры данных, будет повальный копи паст. Хотелось бы без копи паста.

Автор:  Илья Ермаков [ Четверг, 07 Ноябрь, 2013 15:59 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Ну, Вы знакомы с List в Delphi (или в Яве до-дженериковой)?

Вы делаете любую структуру данных, способную хранить ANYPTR (или Object, в терминах Delphi).

И любой динамический объект может быть помещён в эту структуру данных (указатель на него).

Минус, конечно, в том, что лишняя нагрузка на дин. память (которой нет в STL-е). Однако всякие Яво-Шарпы всё равно хранят указатели, у них всё в куче...

Так что решение имеет недостатки только перед самим КП, на котором можно многое без нагрузки на кучу. Ну и перед С++-ами-STL-ями :)

Автор:  Евгений Темиргалеев [ Четверг, 07 Ноябрь, 2013 16:11 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Jordan писал(а):
Если по числу объектов писать структуры данных, будет повальный копи паст. Хотелось бы без копи паста.


В не зависимости от того, обобщённая реализация или нет, она должна быть. И Вы собираетесь её писать. Так?

Тогда у меня к Вам просьба. Напишите реализацию например, списка, например для INTEGER; основные операции --- на Ваше усмотрение. И приведите нам здесь полный исходный текст реализации. На Си и на КП. Пожалуйста.

Автор:  Пётр Кушнир [ Четверг, 07 Ноябрь, 2013 16:17 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

http://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BB%D0%BB%D0%B5%D0%BA%D1%86%D0%B8%D1%8F_(%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5)

Автор:  Madzi [ Четверг, 07 Ноябрь, 2013 16:23 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Вроде как на форуме уже была такая тема. С обобщёнными списками и т.п.

Автор:  Jordan [ Четверг, 07 Ноябрь, 2013 17:07 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Илья Ермаков писал(а):
Ну, Вы знакомы с List в Delphi (или в Яве до-дженериковой)?

Вы делаете любую структуру данных, способную хранить ANYPTR (или Object, в терминах Delphi).

И любой динамический объект может быть помещён в эту структуру данных (указатель на него).


В общем через pointer в паскале или void* в си. Я хотел более культурно сделать.

Евгений Темиргалеев писал(а):
В не зависимости от того, обобщённая реализация или нет, она должна быть. И Вы собираетесь её писать. Так?

Тогда у меня к Вам просьба. Напишите реализацию например, списка, например для INTEGER; основные операции --- на Ваше усмотрение. И приведите нам здесь полный исходный текст реализации. На Си и на КП. Пожалуйста.


Я не совсем понял зачем Вам это? integer мне не нужен, мне нужно хранить структуры. И чем Вам не нравится реализация выше. Вот на си, на си была проба пера.

Банально, шлёпаем в начало списка.
Код:
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

bool point_in_rect(int px, int py, int x, int y, int w, int h)
{
  if ((px >= x) && (py >= y) && (px <= x + w) && (py <= y + h))
  {
    return true;
  }
  else
  {
    return false;
  }
}

typedef struct _button_t button_t;

struct _button_t
{
  char * name;
  int pos_x;
  int pos_y;
  int size_w;
  int size_h;
  button_t * next;
};

button_t * table;
button_t * i;

button_t * button_new(char * name)
{
  button_t * p = (button_t*)malloc(sizeof(button_t));
  p->name   = strdup(name);
  p->next = table;
  table = p;
  return p;
}

button_t * button_find_pos(int x, int y)
{
  button_t * p = table;
  while (p != NULL)
  {
    if (point_in_rect(x, y, p->pos_x, p->pos_y, p->size_w, p->size_h) == true)
    {
      return p;
    }
    p = p->next;
  }
  return NULL;
}

int main(int argc, char **argv)
{
  button_new("1");
  button_new("2");
  button_new("3");
  button_new("4");
  button_new("5");
 
  i = table;
 
  while (i != NULL)
  {
    printf("%s\n", i->name);
    i = i->next;
  }
   return 0;
}


Madzi писал(а):
Вроде как на форуме уже была такая тема. С обобщёнными списками и т.п.


Да, то самое. Спасибо мне нужен был пример реализации.


Всём. Товарищи форумчани, тема не с++ vs кп. Я хотел узнать как на кп, борются с лишним кодом. Возможно ли для этого, заюзать расширенные записи.

Автор:  Kemet [ Четверг, 07 Ноябрь, 2013 17:13 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Jordan,
у меня такое ощущение, что не совсем представляешь что тебе нужно, и оппонентам приходится за тебя додумывать.
Что для тебя "обобщенный список" и "обобщенное программирование"?

Автор:  Евгений Темиргалеев [ Четверг, 07 Ноябрь, 2013 17:21 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Jordan писал(а):
Вот на си, на си была проба пера.
Давайте теперь на КП. И реализацию на Си поправьте, там утечка памяти.

Автор:  Евгений Темиргалеев [ Четверг, 07 Ноябрь, 2013 20:20 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Jordan писал(а):
Код:
bool point_in_rect(int px, int py, int x, int y, int w, int h)
{
  if ((px >= x) && (py >= y) && (px <= x + w) && (py <= y + h))
  {
    return true;
  }
  else
  {
    return false;
  }
}

...
button_t * button_find_pos(int x, int y)
{
  button_t * p = table;
  while (p != NULL)
  {
    if (point_in_rect(x, y, p->pos_x, p->pos_y, p->size_w, p->size_h) == true)
    {
      return p;
    }
    p = p->next;
  }
  return NULL;
}
...
Пара советов
1) Касательно return в середине button_find_pos рекомендую посмотреть 11 страницу в http://www.inr.ac.ru/~info21/pdf/i21.pdf. Есть и более общий материал на тему правильного написания циклов --- м.б. тов. Ермаков даст ссылку.
2) point_in_rect можно записать короче (Хотя творческий процесс развития языка Си на месте не стоит. Поэтому не удивлюсь, если при новых стандартах эта запись может быть и не эквивалентной. Потому ответственность касательно Си с себя снимаю :) )
Код:
bool point_in_rect(int px, int py, int x, int y, int w, int h)
{
  return ((px >= x) && (py >= y) && (px <= x + w) && (py <= y + h));
}

Автор:  Jordan [ Четверг, 07 Ноябрь, 2013 20:42 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Евгений Темиргалеев писал(а):
Давайте теперь на КП. И реализацию на Си поправьте, там утечка памяти.


Так то да, но программа быстро отработала, а windows память освободил.

Код:
  i = table;
  while (i != NULL) {
    i = table->next;
    free(table);
    table = i;
  }


В этом преимущество сборщика мусора.

Евгений Темиргалеев писал(а):
1) Касательно return в середине button_find_pos рекомендую посмотреть 11 страницу в http://www.inr.ac.ru/~info21/pdf/i21.pdf. Есть и более общий материал на тему правильного написания циклов --- м.б. тов. Ермаков даст ссылку.


Не хотелось бы начинать холивар. Но ведь это частность. Сам алгоритм правилен, отрабатывает как надо. Цель же в этом?

Если по правилам то так
Код:
button_t * button_find_pos(int x, int y)
{
  button_t * p = table;

  while (p != NULL) && (point_in_rect(x, y, p->pos_x, p->pos_y, p->size_w, p->size_h) != true)
  {
    p = p->next;
  }

  return p;
}


В любом случае если p не найден, он будет NULL - что оповещает об отсутствии объекта в данных координатах.

Автор:  Евгений Темиргалеев [ Четверг, 07 Ноябрь, 2013 21:41 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Jordan писал(а):
Евгений Темиргалеев писал(а):
Давайте теперь на КП. И реализацию на Си поправьте, там утечка памяти.

Так то да, но программа быстро отработала, а windows память освободил.
Свою обобщённую библиотеку Вы планируете так же писать? Чтобы память освобождалась по завершении программы?
Jordan писал(а):
Не хотелось бы начинать холивар. Но ведь это частность. Сам алгоритм правилен, отрабатывает как надо. Цель же в этом?
---

Вы с какой целью пришли в этот раздел? Чтобы пререкаться? Если да, то я пас.

Автор:  Илья Ермаков [ Четверг, 07 Ноябрь, 2013 21:44 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Jordan писал(а):
(point_in_rect(x, y, p->pos_x, p->pos_y, p->size_w, p->size_h) != true)


эмм, а это как понимать - зачем Вы допустили такую "молодёжную" тавтологию, как сравнение с TRUE/FALSE?

Автор:  ilovb [ Четверг, 07 Ноябрь, 2013 21:50 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Илья, это вообще тайна великая. У нас практический каждый новый кодер так пишет.

2 Jordan:
Цитата:
Цель же в этом?

Не только. Практически так же важна понятность кода.

Программы/алгоритмы не только для исполнения. Они еще и для чтения. Работающая но непонятная программа - это плохая программа.

Автор:  Евгений Темиргалеев [ Четверг, 07 Ноябрь, 2013 21:54 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Или давайте писать дальше на КП. Что там выходит? Вставка элемента в начало списка, поиск элемента.

И элемент списка лучше всё-таки возьмте int. Чтобы сравнить было проще. Ведь для обобщённого списка это не важно. Разве не так?

Автор:  Alexey Veselovsky [ Четверг, 07 Ноябрь, 2013 22:04 ]
Заголовок сообщения:  Re: Как написать обобщённый список на ББ.

Илья Ермаков писал(а):
Jordan писал(а):
(point_in_rect(x, y, p->pos_x, p->pos_y, p->size_w, p->size_h) != true)


эмм, а это как понимать - зачем Вы допустили такую "молодёжную" тавтологию, как сравнение с TRUE/FALSE?


В сях это бывает вполне оправдано - четко виден тип возвращаемого значения point_in_rect.

Страница 1 из 3 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/