В (Свободном) Паскале может ли функция возвращать значение, которое может быть изменено без разыменования? - PullRequest
0 голосов
/ 10 июля 2019

В Паскале я понимаю, что можно создать функцию, возвращающую указатель, который может быть разыменован, и затем присвоить ему значение, например, в следующем (неприятно бесполезном) примере:

type ptr = ^integer;
var d: integer;

function f(x: integer): ptr;
    begin
        f := @x;
    end;

begin
    f(d)^ := 4;
end.

Итеперь d равно 4.

(Фактическое использование - доступ к части довольно сложной структуры данных массива записей. Я знаю, что класс будет лучше, чем массив вложенных записей, но это не так.Мой код (это TeX: The Program) и был написан до того, как реализации Pascal поддерживали объектную ориентацию.Код был написан с использованием языка, основанного на Pascal, который добавил макросы, которые расширяются до того, как компилятор их видит. Таким образом, вы можете определить некоторыемакрос m, который принимает аргумент x и расширяется до thearray[x + 1].f1.f2 вместо того, чтобы записывать это каждый раз; использование будет m(x) := somevalue. Я хочу скопировать эту функцию с помощью функции вместо макроса.)

Однако возможно ли достичь этой функциональности без оператора ^?Может ли функция f быть написана так, чтобы f(x) := y (без каретки) присваивал значение y x?Я знаю, что это глупо, и ответ, вероятно, нет, но мне просто (а) не очень нравится его внешний вид, и (б) я пытаюсь имитировать именно ту форму макроса, о которой я упоминал выше.

1 Ответ

1 голос
/ 10 июля 2019

Ссылки не являются объектами первого класса в Pascal, в отличие от языков, таких как C ++ или D. Поэтому простой ответ заключается в том, что вы не можете напрямую достичь того, что вы хотите.

Использование указателя, как вы иллюстрировали, является одним из способовдобиться того же эффекта, хотя в реальном коде вам нужно будет возвращать адрес объекта, время жизни которого выходит за пределы срока действия функции.В вашем коде это не так, потому что аргумент x действителен только до тех пор, пока не вернется функция.

Вы можете использовать расширенную запись с перегрузкой оператора для инкапсуляции указателя и, таким образом, для инкапсуляции кода разыменования указателя.Это может быть хорошим вариантом, но это очень сильно зависит от вашей общей проблемы, о которой мы не видим.

...