OberonCore
https://forum.oberoncore.ru/

Указатель на массив
https://forum.oberoncore.ru/viewtopic.php?f=29&t=790
Страница 1 из 1

Автор:  Димыч [ Воскресенье, 23 Декабрь, 2007 11:58 ]
Заголовок сообщения:  Указатель на массив

Уважаемые коллеги!
Подскажите пожалуйста, как корректно переписать с C++ на КП следующую конструкцию:

unsigned char* buffer = new unsigned char[frame_width * frame_height * 3];
... работа с массивом
unsigned char* buffer_part = buffer + frame_width * 3 * 20 + 3 * 20;
т.е. получить указатель на часть массива и использовать ее как новый массив меньшего размера.

Как вообще реализовать адресную арифметику или чем ее заменить?
Спасибо.

Автор:  AVC [ Воскресенье, 23 Декабрь, 2007 13:36 ]
Заголовок сообщения:  Re: Указатель на массив

Димыч писал(а):
Уважаемые коллеги!
Подскажите пожалуйста, как корректно переписать с C++ на КП следующую конструкцию:

unsigned char* buffer = new unsigned char[frame_width * frame_height * 3];

Примерно так:
Код:
p: POINTER TO ARRAY OF SHORTCHAR;
...
NEW(p, frame_width * frame_height * 3);


Димыч писал(а):
Как вообще реализовать адресную арифметику или чем ее заменить?
Спасибо.

Смотря для чего Вы используете адресную арифметику.

Автор:  Илья Ермаков [ Воскресенье, 23 Декабрь, 2007 13:44 ]
Заголовок сообщения:  Re: Указатель на массив

Цитата:
т.е. получить указатель на часть массива и использовать ее как новый массив меньшего размера.

Сначала давайте разберёмся, для чего это нужно. Может быть, лучше использовать многомерный массив? Учитывайте, что в С/С++ такие массивы толком не поддерживаются, и часто их эмулируют в одномерном, "играя" индексами. В КП же прекрасная поддержка многомерности.
Если же требуется просто часть линейного массива, почему явно не использовать индексы интервала [beg, end)?
Предположим, группа функций работает с фрагментами массива - ну и передавайте POINTER TO ARRAY... и пару beg, end. Если же работает не просто группа функций, а это это как-то выносится в интерфейс какой-то библиотеки, то хороший тон вообще обернуть это в отдельный тип. Например, сделать тип Array, у которого есть метод GetElems(i, count: INTEGER; OUT elems: ARRAY OF BaseType) и GetSubArray (beg, end: INTEGER): Array.

Эмулировать Си можно, но крайне не рекомендуется. Для этого нужно использовать средства псевдомодуля SYSTEM (см. документацию ББ "Особенности платформы" (Platform-Speciffic Issues)). Тогда указатель на подмассив объявляется как TYPE SubArray = POINTER TO ARRAY [untagged] OF BYTE и затем берётся так: suba = SYSTEM.VAL(SubArray, SYSTEM.ADR(array[i])). Однако это КРАЙНЕ НЕ РЕКОМЕНДУЕТСЯ. При обращении с таким "диким подмассивом", поскольку он безтеговый, не будет выполняться проверка выхода за границы (не то что подмассива, но даже и базового массива), т.е. вся безопасность памяти идёт лесом. Кроме того, подмассив не будет являться якорем для сборщика мусора. Т.е. если ссылка на подмассив есть, а ссылка на базовый уже исчезла, он будет собран сборщиком, и при обращении к подмассиву Вы получите фатальный сбой...

Автор:  Димыч [ Воскресенье, 23 Декабрь, 2007 17:42 ]
Заголовок сообщения:  Re: Указатель на массив

Илья Ермаков писал(а):
Цитата:
т.е. получить указатель на часть массива и использовать ее как новый массив меньшего размера.

Цитата:
Сначала давайте разберёмся, для чего это нужно.

Есть задумка перевести на XDS/CP библиотеку Anti-Grain Geometry. Причем не просто сделать подгружаемую DLL и импортировать ее, а полностью переписать на Oberon.
Цитата:
Может быть, лучше использовать многомерный массив? Учитывайте, что в С/С++ такие массивы толком не поддерживаются, и часто их эмулируют в одномерном, "играя" индексами.

Именно так это и реализовано в AGG.
Цитата:
Если же требуется просто часть линейного массива, почему явно не использовать индексы интервала [beg, end)?

Я хотел использовать интервальный механизм, но это меняет логику алгоритмов. По крайней мере это меняет логику самого низкого слоя кода.

Цитата:
Эмулировать Си можно, но крайне не рекомендуется. Для этого нужно использовать средства псевдомодуля SYSTEM (см. документацию ББ "Особенности платформы" (Platform-Speciffic Issues)). Тогда указатель на подмассив объявляется как TYPE SubArray = POINTER TO ARRAY [untagged] OF BYTE и затем берётся так: suba = SYSTEM.VAL(SubArray, SYSTEM.ADR(array[i])).

Собственно, вопрос я задал тогда, когда такой код у меня получился на XDS, но не получился на CP. Вопрос состоял в атрибуте [untagged].

Цитата:
Однако это КРАЙНЕ НЕ РЕКОМЕНДУЕТСЯ. При обращении с таким "диким подмассивом", поскольку он безтеговый, не будет выполняться проверка выхода за границы (не то что подмассива, но даже и базового массива), т.е. вся безопасность памяти идёт лесом. Кроме того, подмассив не будет являться якорем для сборщика мусора. Т.е. если ссылка на подмассив есть, а ссылка на базовый уже исчезла, он будет собран сборщиком, и при обращении к подмассиву Вы получите фатальный сбой...


Еще предстоит поэкспериментировать, но над механизмом двумерного массива я подумаю...

Автор:  Илья Ермаков [ Воскресенье, 23 Декабрь, 2007 18:46 ]
Заголовок сообщения:  Re: Указатель на массив

А Вы смотрели порт AGG на Object Pascal? Может быть, его перенести на Оберон легче, чем С++-сный оригинал?

Автор:  AVC [ Воскресенье, 23 Декабрь, 2007 18:59 ]
Заголовок сообщения:  Re: Указатель на массив

IMHO, типовой пример работы с подмассивами на Обероне (Модуле, Паскале) - быстрая сортировка Хоара.
Например, см. 2-ю главу ADS (Algorithms and Data Structures).

Автор:  Димыч [ Среда, 26 Декабрь, 2007 12:13 ]
Заголовок сообщения:  Re: Указатель на массив

Илья Ермаков писал(а):
А Вы смотрели порт AGG на Object Pascal? Может быть, его перенести на Оберон легче, чем С++-сный оригинал?


Смотрел, конечно, с нее и перевожу.
AGGPAS использует ту же адресную арифметику, переписанную на Паскаль :)

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