Как воссоздать функцию, извлекающую самый высокий элемент объекта?

Мой план состоит в том, чтобы сделать функцию, которая извлекает самый высокий элемент объекта, так сказать, верхний диапазон массива. Другими словами, я пытаюсь получить код функции High().

Что я пробовал до сих пор:

 function High2(var X):integer;
 begin
   Result:=Pbyte(Cardinal(@X)-1)^-1;
 end;

Приведенная выше функция должна считывать значение (длину) перед позицией первого элемента в объекте (массив/строка) и возвращать его, уменьшенное на 1. Однако она не возвращает правильные результаты ни для статического, ни для динамического типа массива.

Как воссоздать функцию High() в Паскале?


person Ivan Prodanov    schedule 26.09.2009    source источник
comment
Я не имею ни малейшего представления, чего вы хотите добиться. Можете ли вы привести пример?   -  person Uwe Raabe    schedule 27.09.2009


Ответы (2)


Не уверен, зачем вам это нужно, если в Delphi уже есть встроенная магическая функция компилятора High(), но ладно, поехали.

Статические массивы: невозможно. Информация о размере не сохраняется во время выполнения, поскольку размер известен компилятору и не может измениться. High() просто добавляет необходимое число в код как константу.

Динамические массивы: компилятор преобразует High в вызов DynArrayHigh в системном модуле, который возвращает DynArrayLength — 1. DynArrayLength отступает на 4 байта от начала массива (вы отступаете только на 1) и возвращает длину как целое число. вместо байта.

Надеюсь, это полезно. Почему бы вам просто не использовать High, кстати?

person Mason Wheeler    schedule 26.09.2009
comment
FWIW, в Delphi 2010 расширенный RTTI фактически хранит количество элементов (плоских) в статических массивах, даже если массив не имеет управляемого типа. Это необходимо для трассировки кучи. - person Barry Kelly; 27.09.2009
comment
Конечно, эти данные не размещаются совместно с данными статического массива, поэтому без общего вывода или другого способа передачи связанного PTypeInfo это не поможет. - person Barry Kelly; 27.09.2009
comment
@Mason Wheeler, я бы хотел использовать Turbo Pascal, который очень старый, и я не уверен, есть ли в нем функция High (), поэтому я и спросил. - person Ivan Prodanov; 27.09.2009
comment
Джон, в Turbo Pascal есть функция High — посмотрите документацию — но в ней нет динамических массивов, так что вам не к чему ее вызывать. Если вы хотите определить вещи, подобные динамическим массивам, в Turbo Pascal, продолжайте, но вам не нужно дублировать код Delphi, поскольку вы будете отвечать за то, как хранится длина, а также как ее получить. - person Rob Kennedy; 27.09.2009

Функции High() (и Low()) называются "стандартными функциями", что означает, что они встроены в компилятор. Подобно Write и Writeln, они на самом деле не существуют как обычные объявления функций Pascal. Компилятор гарантирует, что они находятся в области модуля «Система» просто для удобства и для того, чтобы разрешить функцию с тем же именем в других областях. Это также позволяет вам квалифицировать их, используя System.High() для явной ссылки на версию модуля System. Поскольку они являются внутренними, компилятор автоматически сгенерирует правильную последовательность кода для рассматриваемого типа. Это также означает, что попытка воспроизвести их полную функциональность практически невозможна. Просто придерживайтесь встроенных стандартных функций.

person Allen Bauer    schedule 26.09.2009
comment
Аллен, существует ли документ, который описывает и детализирует функции, которые являются частью магической группы компилятора, такие как High, Low, Writeln и т. д.? - person RRUZ; 27.09.2009
comment
Rruz, документация Delphi описывает эти функции. Однако нет ничего, что подробно рассказывало бы о том, как они работают, потому что эта информация вас не касается, поскольку является деталью реализации, которая может измениться с каждым выпуском Delphi. - person Rob Kennedy; 27.09.2009