Главная » Free Pascal » Оформление функций Free Pascal

0

Функция представляет собой частный вид процедуры, результатом работы ко- торой является единственное значение. Его принято называть значением, которое возвращает функция. Такой результат позволяет использовать функцию в качестве операнда любой формулы соответствующего типа:

y:=f1(x,z)*sin(f2(u))+f3(v);

Объявление функции начинается с заголовка, который в общем случае имеет вид:

function name_fun[(list_arg)]:tip; [directives];

По сравнению с заголовком директивы здесь присутствует новый обязательный компонент: tip — тип возвращаемого значения.

В качестве примера оформления функции в листинге 9.2 приводится фрагмент,

реализующий вычисление скалярного произведения векторов в традициях ранних версий Паскаля.

   Листинг 9 .2 .  Выч исл е ние  с к а л я рного  про извед е ния                                                                 

const

N = 10;

type

vecN = array [1..N] of double;

var

a,b : vecN; c : double

function vec_mult(A,B:vecN):double; var

i: byte; s: double;

begin

s := 0;

for i:=1 to N do

s := s+A[i]*B[i]; vec_mul := s;

end;

Дополнительной спецификой оформления функций является способ возврата вычисленного результата: его надо присвоить "переменной", имя которой совпада- ет с именем функции.

В языке Object Pascal и во всех версиях Delphi появился более удобный способ возврата значения функции: введена специальная системная переменная c именем

Result. Ее не надо объявлять, и тип этой "переменной" всегда совпадает с типом функции. Поэтому в предыдущем примере оператор vec_mul:=s; можно заменить на Result:=s;. На самом деле возможности переменной Result немного шире: она может использоваться как в левой, так и в правой части оператора присваивания. Поэтому оформление функции vec_mult могло выглядеть следующим образом: function vec_mult(A,B:vecN):double;

var

i: byte; begin

Result := 0;

for i:=1 to N do

Result := Result + A[i]*B[i];

end;

В языке Free Pascal появилась еще одна возможность возврата значения вычис- ляемой функции:

exit(s);

Этот формат заимствован из языка C, C++, только служебное слово return

(возврат) здесь заменено на exit.

В рамках одной функции можно одновременно пользоваться и переменной с именем Result, и переменной с именем функции. Например

function qq : integer; begin

qq:=1;              {значение функции равно 1} Result:=Result*2;    {значение функции равно 2} Result:=Result+3;    {окончательное значение функции равно 5}

end;

Чтобы понять разницу между передачей параметра функции по значению и по адресу, рассмотрим две функции — f1 и f2, которые возвращают удвоенное значе- ние своего аргумента:

function f1(x:integer):integer; begin

x:=x*2; Result:=x;

end;

Аргумент функции f1 передается по значению, поэтому изменение параметра x в теле функции не оказывает никакого влияния на фактический аргумент, заданный в конкретном обращении:

var

y: integer=2; z: integer;

begin

z:=f1(y);     {z=4, y=2}

y:=f1(z+1);   {z=4, y=10}

Совсем по-другому работает функция f2, которая получает свой аргумент по адресу:

function f2(var v : integer):integer; begin

x:=x*2; Result:=x;

end;

Обращение z:=f2(y); приведет не только к изменению значения переменной z (z=4), но одновременно изменится и значение переменной y (y=4). К функции f2 нельзя обращаться с аргументом, представленным формулой.

Очень интересную возможность представляет использование параметра без описания его типа в заголовке функции или подпрограммы. Рассмотрим пример с функцией Equal, которая умеет сравнивать данные любого типа (листинг 9.3). Идея ее алгоритма основана на том, что функция кроме адресов сравниваемых данных (а1 и a2) получает и их длину (size) в байтах. Адреса полученных объектов преоб- разуются в адреса однобайтовых массивов достаточно большой длины, и операция сравнения производится побайтно.

   Листинг 9 .3 .  Программа  с ра вне ния  д а нных  л юбого  типа  comp_all                  

program comp_all;

function Equal(var a1,a2; size:word):boolean; type

Bytes=array [0..MaxInt div 2] of byte;

var

N: integer; begin

N:=0;

while (N<size)and(Bytes(a1)[N]=Bytes(a2)[N]) do inc(N); Result:=(N=size);

end;

type

Vector = array [1..10] of integer;

Point = record x,y:integer;

end; var

vec1:Vector=(0,1,2,3,4,5,6,7,8,9);

vec2:Vector=(0,1,2,3,4,5,4,3,2,1);

N : integer=4;

P : Point = (x:2; y:3); begin

writeln(Equal(vec1,vec2,SizeOf(Vector))); writeln(Equal(vec1,vec2,SizeOf(Integer)*N)); writeln(Equal(vec1[3],P,8));

readln; end.

Результат работы программы comp_all приведен на рис. 9.11.

Рис. 9.1. Сравнение данных разного типа

В функции Equal довольно изобретательно реализовано вычисление возвра- щаемого значения. Всякий раз, когда байты, сравниваемые в цикле, совпадают, к переменной N добавляется единица. Если все сравниваемые байты окажутся равны, то после завершения цикла в переменной N должна накопиться величина size и результатом логической формулы (size=N) будет истина. Конечно, работу функции можно было бы прервать досрочно — при обнаружении первой пары несовпадаю- щих байтов:

for N:=1 to size do

if Bytes(a1)[N]<>Bytes(a2)[N]then exit(False); exit(true);

Параметры подпрограмм по умолчанию

В языке Free Pascal имеется возможность объявить процедуру или функцию, у которой значения нескольких последних аргументов списка list_arg заданы со значениями по умолчанию:

function mid3(x1:word; x2:word=1; x3:word=2); begin

Result:=(x1+x2+x3) div 3;

end;

1 Если при компиляции у вас возникают ошибки, полните команду Options ® Compiler и в группе Compiler mode установите опцию Object Pascal extension on или Delphi compatible. (Первая опция предпочтительнее.) — Прим. ред.

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

mid3(6) = 3 // эквивалент обращения mid3(6,1,2) mid3(6,3) = 3 // эквивалент обращения mid3(6,3,2) mid3(6,3,5) = 4

В любом случае параметры, не указанные в обращении, заменяются соответст- вующими значениями по умолчанию.

Источник: Кетков, Ю. Л., Свободное программное обеспечение. FREE PASCAL для студентов и школьников, Ю. Л. Кетков, А. Ю. Кетков. — СПб.: БХВ-Петербург, 2011. — 384 с.: ил. + CD-ROM — (ИиИКТ)

По теме:

  • Комментарии