12.2 Вызов функций

Вверх  Предыдущий  Следующий

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


Вызов функций

1204


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

1.Количество фактических параметров должно быть равно числу объявленных параметров (если не используются значения параметров по умолчанию).

2.Типы параметров должны быть совместимы. Для фактических и объявленных переменных-параметров, типы должны быть такими-же.

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

Существуют случаи, когда компилятор не выполнит вызов функции в выражении. Это случай, когда в режиме Delphi или Turbo Pascal нужно присвоить значение переменной процедурного типа, как показано в следующем примере:

Type

FuncType = Function : Integer;

Var

A : Integer;

 

Function AddOne : Integer;

begin

A:=A+1;

AddOne:=A;

end;

 

Var F:FuncType;

N : Integer;

begin

A:=0;

F:=AddOne; {Присваивание адреса AddOne переменной F, Не вызывается функция AddOne}

N:=AddOne; {N:=1!!}

end.

В приведенном выше листинге, присваивание функции AddOne переменной F не будет вызывать функцию. А присвоение переменной N вызовет функцию AddOne.

Иногда желательно вызвать функцию принудительно, например, в рекурсии. Это может быть сделано путем добавления скобок к имени функции:

function rd:char;

var

c:char;

begin

read(c);

if(c='\')then c:=rd();

rd:=c;

end;

 

var

ch:char;

begin

ch:=rd;

writeln(ch);

end.

Приведённая выше функция будет читать символ и распечатать его. Если введён обратный слеш, то читается второй символ.

Проблема с этим синтаксисом проявляет следующая конструкция:

If F = AddOne Then DoSomethingHorrible;

Что должен сделать компилятор сравнить адреса F и AddOne, или он должен вызвать обе функции, и сравните результат? В режиме FPC и objfpc он рассмотривает процедурную переменную как указатель. Таким образом, компилятор выдаст ошибку несоответствия типов, так как результат вызова функции AddOne целый а F является указателем.

Как же, следует проверить, является ли F указателем на функцию AddOne? Для этого нужно использовать оператор адреса @:

If F = @AddOne Then WriteLn ('функции равны');

Левая часть логического выражения является адресом. Правая часть также, и поэтому компилятор сравнит два адреса. Для сравнения значений, которые возвращают обе функции, вызвать функцию на которую указывает переменная F можно добавленем пустого списка параметров:

If F()=Addone then WriteLn ('функции возвращают одинаковые значения');

Заметим, что поведение, как в последнем примере, не совместимо с синтаксисом Delphi. Включение режима Delphi позволит вам использовать синтаксис Delphi.