|
|
Назад
Раздел "Программирование"
Пользовательские функции
При вызове прдпрограммы-функции работа главной программы на некоторое время приостанавливается
и начинает выполняться функция. Главная программа обычно передает функции какое-то конкретное
знечение, указанное в главной программе. Этот параметр называется фактическим параметром, или аргументом.
Он сопоставляется с некоторым формальным параметром, который является внутренним
объектом подпрограммы. На основе заданных величин вычисляется результат, который возвращается в главную программу
как значение функции.
Структура подпрограммы-функции Подпрограмма-функция начинается с заголовка,
в котором содержится имя функции, имя и тип каждого формального параметра, а также тип результата:
function <имя ф-ции>(<р1>:<тип_р1>;<р2>:<тип_р2>;... ):<тип_рез>;
Например, function sample(x:integer;y:real):real;
Здесь sample - имя функции, x,y - два формальных параметра, тип которых integer
и real соответственно.
Функция возвращает результат типа real.
В момент вызова подпрограммы значения аргументов - фактических параметров - сопоставляются
с именами формальных параметров.
За заголовком функции следуют обявления локальных переменных подпрограммы-функции. Тело
подпрограммы-функции заключается в операторные скобки begin - end;
Примечание. Необходимо помнить о следующих особенностях подпрограммы-функции:
Локальные переменные, объявленные в подпрограмме, никак не связаны с главной программой -
глобальными переменнами - даже при совпадении имен (!).
в отличие от подпрограммы-процедуры подпрограмма-функция возвращает только одно значение;
тип этого результата должен быть указан в заголовке;
тип возвращаемого результата может относиться к простым (неструктурируемым) данным;
в теле функции должен обязательно присутствовать оператор вида <имя функции>:=<результат>
т.е. имени функции присваивается окончательный результат, вычисляемый в подпрограмме;
ни один из параметров функции не должен быть var-параметром, так как ни один из них
не должен получать новое значение в теле функции.
Преимущество использования подпрограмм-функций - возможность тестировать
и отлаживать их независимо от других модулей.
Где размещается подпрограмма-функция. В Паскале главная программа начинается
с декларативной части (раздел объявлений типова данных), в которую, в частности,
входят и описания всех подпрограмм.
Как вызывается подпрограмма-функция. Пользвателские функции могут использоваться как в главной программе, так и в подпрограммах.
При этом формальным параметрам должны быть поставлены в оответствие реальные параметры объявленные в главной программе.
Например, пусть функция sxy(u,v:real):real; вычисляет сумму двух вещественных чисел, а в главной программе вычисляется с помощью с этой функции следующий фрагмент:
begin...................
readln (x,y);
s:=sxy(10,5)/sxy(x,y);
.........................
end.
В числителе функция sxy возвращает сумму (10+5), а в знаменателе функция sxy будет складывать два числа, которые вводятся с клавиатуры.
Примеры пользовательских функций
Пример 1. Функция sing возвращает знак вещественного числа.
function sing(x:real):integer;
begin
if x=0 then sign:=0;
if x>0 then sign:=1;
if x<0 then sign:=-1;
end;
Пример 2. функция находит сумму квадратов первых n чисел:
1*1+ 2*2+ 3*3+ 4*4+5*5+...n*n + ...
function sumsqr(n:integer);
var i:imteger;
begin
sum :=0;
for i:=1 to n do
sum:=sum + i*i;
sumsqr:=sum
end;{sumsqr}
Пример 3.
Функция находит наибольшее из трех целых чисел a,b,c.
function max3(a,b,c:integer): integer;
var
max:integer; {условно наибольшее}
begin
{сначала находим наибольшее из a и b}
if a > > =b
then max:=a
else max:=b;
{теперь сравним max с числом c}
if max > > c
then max3:=max
else max:=c
end; {max3}
Пример 4. Во многих задачах возникает необходимость вычисления бесконечных рядов c заданной точностью с помощью рекуррентных соотношений. Рассмотрим эту проблему на примере вычисления суммы ряда
S=x – x3/3! + x5/5! - x7/7! +...
с заданной точностью eps.
На первый взгляд задача может показаться достаточно сложной. Однако ситуация сильно упрощается, если использовать рекуррентную формулу,
с помощью которой каждый последующий член ряда выражается через предыдущий., т.е. справедливо соотношение:
un = q un-1
Попробуем определить q, рассмотрев последовательно отношение второго члена к перовому, третьего ко второму, четвертого к третьему и т.д.:
q1= u2 / u1
= - (x3/3!)/x
= - x2/(2 * 3)
q2= u3 / u2
= - (x5 / 5!) / (x3/3!)
= - x2/(4 * 5)
q3= u4 / u3
= - (x7 / 7!)/ (x5/ 5!) = - x/(6 * 7)
….......................................................
Нетрудно видеть, что для произвольного q справедлива формула:
q= - x2 / k/(k+1), где k= 2, 4, 6, ...
Таким образом, положив первый член ряда равным x , можно вычислить следующий члена ряда, используя оператор:
u:= - u* sqr(x)/k/(k+1);
Ниже приводится подпрограмма-функция mysin(x) для вычисления ряда
Вариант 1.
Function mysin(x:real): real;
const eps=0.00001; {точность вычиcления}
var
u: real; { член ряда}
s: real; {сумма ряда}
к : integer; {номер члена ряда}
begin
s:=0; {обнуление суммы}
к:=0; {начальное значение переменной k}
u:=x; {первый член ряда}
while abs(u) > eps do {пока абсолютное значение члена ряда больше точности, выполняем}
begin
s:=s+u; {суммируем ряд}
к:=к+2; { формируем четное число }
u:= - u * sqr(x) / к/ (к+1) ; {вычисляем следующий член ряда}
end;
mysin:= s; {имени функции присваиваем результат s}
end; {function}
Пример 5. Задача о простых числах. Простым числом называется натуральное число, которое не имеет делителей -
делится только на себя и на единицу. Функция выдает "флаг" f:=true; если число является простым.
Вариант 1.
function prost(j:word):boolean;
var
f:boolean; {"флаг"}
m:word; {возможные делители}
begin
f:=true;{гипотеза, что число простое}
{Проверка производится до первого делителя}
m:=2; {первый возможный делитель}
while (m <j) and f do
begin
if j mod m=0 then f:=false;
m:=m+1
end;{while}
end;{prost}
Вариант 2.Поскольку четные числа не простые, алгоритм рассматривает только нечетные числа.
Для этого используется функция odd(j).
function prost(j:word):boolean;
var
f:boolean; {"флаг"}
m:word; {возможные делители}
n:word;
begin
f:=true;{гипотеза, что число простое}
{Проверка производится до первого делителя}
if odd(j) then {рассматриваем только нечетные числа}
begin
m:=1;
n:=round(sqrt(j));
repeat
m:=m+2;
if j mod m=0 then f:=false
until f and (m>>=n)
end
else f:=false;
end;{prost}
Задание 1
1. Напишите программу для вычисления sin(x) и mysin(x) при разной точности eps для значений x=pi/2 и pi/4 и занесите результаты в табличку:
| Eps |
sin x |
mysin(x) |
| 0.01 |
... |
... |
| 0.001 |
... |
... |
| 0.00001 |
... |
... |
Вывод. Для Sin(x) справедливо приближенное представление в виде бесконечного ряда:
Sin(x) =x – x3/3! + x5/5! - x7/7! +...
Контрольные вопросы
Как влияет значение eps на результат вычислений?
Можно ли использовать для решения этой задачи цикл repeat… until? Если да, то что изменится?
Задание 2 Проанализируйте приведенные ниже листинги функций и допишите комментарий.
Function fsum(u:mas;n:integer):integer;
{Суммирование элементов массива целых чисел}
var
i,s:integer;
begin
s:=0;
for i:=1 to n do
s:=s+u[i];
fsum:=s
end; {fsum}
Function fmin(u:mas;n:integer):integer;
{Определение минимального элемента в массиве целых чисел}
var
i,s:integer;
begin
min:=u[i];
for i:=2 to n do
if u[i]
fmin:=min
end; {fmin}
Function fmax(u:mas;n:integer):integer;
{Определение максимального элемента в массиве целых чисел}
var
i,s:integer;
begin
max:=u[i];
for i:=2 to n do
if u[i]>max then max:=u[i];
fmin:=min
end; {fmax}
Function fsum_cifr(k:integer):integer;
{Определение суммы цифр целого числа}
var
c,s:integer;
begin
s:=0;
while n<>0 do
begin
s:=s+k mod 10;
k:=k div 10
end;
fsum_cifr:=s
end; {fsum_cifr}
Упражнения
1. Укажите ошибки в заголовках функций:
function ab(k:byte);
function sgeron(a,b,c):integer;
2.Составьте подпрограммы-функции
для расчета суммы кубов первых n чисел;
для расчета площади треугрльника по трем сторонам по формуле Герона.
Примечание. При написании функции предусмотрите проверку существования треугольника.
3. Напишите подпрограмму-функцию для вычисления суммы делителей целого положительного числа.
4. Напишите подпрограмму-функцию для вычисления суммы и произведения цифр целого положительного числа.
5. Напишите подпрограмму-функцию для определения, является ли число совершенным. Совершенное число - это число,
которое равно сумме своих делителей, увеличенной на единицу. Например, совершенным является число 6: 2+3+1.
|
|