5.4. Функции пользователя

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

• Функция передает в программу результат своей работы — единственное значение, носителем которого является имя самой функции.

• Имя функции может входить в выражение как операнд. Функция возвращает результат в точку своего вызова.

Функция, определенная пользователем, состоит из заголовка и тела функции. Заголовок содержит зарезервированное слово function, имя функции, заключенный в круглые скобки необязательный список формальных параметров и, обратите внимание — в отличие от процедуры, тип возвращаемого функцией значения:

function ИмяФункции(ФормальныеПараметры) : ТипРезультата;

Например:

function fibo(n: integer): integer; { n — формальный параметр }
function instep(a,b: real): real; { a,b — формальные параметры }
function normrandom : double; { формальных параметров нет }

Имя функции уникально в пределах программы.

Тело функции по своей структуре аналогично обычной программе:

function ИмяФункции(ФормальныеПараметры) : ТипРезультата;
  ( Описательная часть функции }
begin
  ( Инструкции исполнительной части функции }
  ИмяФункции := Результат;
end;

Обратите внимание — в разделе операторов функции должен находиться по крайней мере один оператор, который присваивает ее имени значение, возвращаемое как результат работы функции. Если таких присваиваний несколько, то результатом выполнения функции будет значение последнего оператора присваивания. Если же такой оператор отсутствует или не был выполнен, то значение, возвращаемое функцией, не определено.

В отличие от процедуры, вызов функции не оформляется в виде отдельного оператора. Обращение к функции осуществляется путем использования указателя функции в качестве операнда в некотором выражении. Указатель функции представляет собой имя функции с необязательным списком аргументов — фактических параметров. Требования к ним такие же, как и в случае процедуры.

Например:

writeln(fibo(i)); { параметр — значение переменной }
c:=instep(2,8); ( параметры — непосредственно значения }
write(normrandom: 10:3); { фактические параметры не указаны, т.к. в вызываемой функции нет формальных параметров }

Программа, представленная в листинге 5.4, использовала процедуру для вычисления членов ряда Фибоначчи. Листинг 5.5 решает эту задачу при по¬мощи функции.

Листинг 5.5. Программа вычисления членов ряда Фибоначчи (вариант № 2)

function fibo(n: integer): integer;
{ функция вычисления чисел Фибоначчи }
var fn,fn1,fn2,k: integer;
begin
  fn1:=1;
  fn:=0;
  for k:=1 to n do
    begin
      fn2:=fn1;
      fn1:=fn;
      fn:= fn1+fn2;
    end;
  fibo:= fn; { имени функции присваивается возвращаемое значение }
end;
{ основная программа }
var 1, n: integer;
begin
write('Введите число членов ряда Фибоначчи: '); readln(n);
for i:= 1 to n do writeln(fibo(i)); { вызов функции }
end.

Представленная программа менее эффективна, чем предыдущая (см. листинг 5.4). В соответствии с программой (листинг 5.5) числа Фибоначчи вычисляются, печатаются и "забываются". При поиске нового, большего числа приходится повторять те же самые действия.

Рассмотренный выше листинг 3.10 содержал программу решения квадратного уравнения. Выполним ту же задачу с использованием функции (листинг 5.6).

Листинг 5.6. Решение квадратного уравнения (вариант № 2)


function kvadrur(a,b,с: real; var xl,x2: real): integer;
{ функция решение квадратного уравнения }
{ a,b,c — коэффициенты уравнения }
{ xl,x2 — корни уравнения }
{ значение функции — количество корней или }
{ -1, если исходные данные неверны }
var d: real; { дискриминант }
begin
  if a=0 then kvadrur:=-1
  else
    begin
      d:=b*b-4*a*c;
      if d<0 then kvadrur:=0 { вещественного решения нет }
        else
          begin
            if d>0 then kvadrur:=2 { два разных корня }
              else kvadrur:=1; { корни одинаковые }
            x1:=(-b+sqrt(d))/(2*a);
            x2:=(-b-sqrt(d))/(2*a);
          end;
    end;
end;
{ основная программа }
var
  a,b,c: real; { коэффициенты уравнения }
  xl,x2: real; { корни уравнения }
begin
  writeln('Введите в одной строке коэффициенты а, b, с'); readln(a,b,c);
  case kvadrur(a,b,c,x1,x2) of
    -1: writeln('Ошибка исходных данных');
    0: writeln('Уравнение имеет комплексные корни');
    1: writeln('х=',xl:7:3,', корни одинаковы');
    2: writeln ('xl=\xl: 7:3, '; х2=',х2:7:3);   end;
end.

Обратите внимание — приведенный пример позволяет сделать важный вывод, расширяющий наше представление о функциях. Функция может возвращать более одного результата, если в ней используются параметры-переменные.

Листинг 5.7 содержит программу, вычисляющую значение корня х уравнения f(х) = 4 — ех — 2х2 = 0 методом половинного деления (дихотомии).

Листинг5.7. Вычисление корня уравнения методом половинного деления

function f(x: real): real;
begin
  f:=4-exp(x)-2*x*x; { анализируемое уравнение }
end;
{ основная программа }
var a,b,fa,fc,c,eps: real;
begin
  write('Границы интервала изоляции корня — а и b: ');readln(a,b);
  write ('Погрешность вычисления корня: '); read (eps);
  fa:= f(a); { расчет f на левом конце отрезка }
  while b-a > eps do
    begin
      c:=(a+b)/2; fc:=f(c); { делим отрезок пополам }
      if fa*fc <= 0 then b:=c
        else
          begin
            a:=c; fa:=fc;
          end;
    end;
  writeln('f =',f (a) :10:7, 'прих=', a:10:7);
end.

 предыдущая         меню        вверх         следующая

Hosted by uCoz