Глава 7
Подпрограммы 7.1. Понятие подпрограммы
Подпрограммы являются одним из основных механизмов структу-рирования программ в большинстве языков программирования. В процессе разработки программы программист имеет возможность разбить задачу на подзадачи, оформив каждую подзадачу в виде программной единицы - подпрограммы, а затем соответствующим образом организовать их взаимо-действие.
Подпрограмма, как и программа, состоит из трех разделов:
- заголовка;
- описаний;
- операторов.
Заголовок представляет собой интерфейсную часть подпрограммы. Он содержит имя подпрограммы и, возможно, список формальных параметров.
Разделы описаний и операторов составляют тело подпрограммы.
При обращении к подпрограмме указываются ее имя и список факти-ческих параметров. Количество и типы фактических параметров должны сов-падать с количеством и типами соответствующих формальных параметров.
Выполнение подпрограммы завершается по исполнении последнего оператора, входящего в ее блок. Немедленное завершение работы подпро-граммы реализуется процедурой Exit .
Управление передается в точку вызова. Исполнение процедуры Exit в главной программе немедленно завершает ее работу.
В языке Паскаль определены подпрограммы двух видов: функции и процедуры.
7.2. Функции
Функция определяет одно единственное значение, которое исполь-зуется при вычислении выражения. Это значит, что результатом работы функции может быть простой (неструктурный), а также ссылочный тип.
Структурный тип не может являться результатом работы функции. В языке Турбо Паскаль для типа STRING сделано исключение, что несколько нарушает концептуальную целостность языка, но в ряде случаев предостав-ляет определенные удобства.
Заголовок функции имеет вид: FUNCTIN Funname (FORM):typres , где Funname - имя функции, FORM - список формальных параметров, typres - тип результата.
Формальными параметрами могут быть:
- переменные;
- имена подпрограмм.
Среди операторов, входящих в раздел операторов, должен быть хотя бы один, присваивающий значение имени функции. При этом имя функции может использоваться только в левой части оператора присваивания. Если в процессе выполнения тела подпрограммы не выполнится ни один оператор, присваивающий значение имени функции, то значение функции считается неопределенным.
При обращении к функции указывается ее имя и в скобках - список фактических параметров. Фактическими параметрами могут быть:
- выражения;
- имена подпрограмм.
Количество и типы фактических параметров должны совпадать с ко-личеством и типами соответствующих формальных параметров.
Стандартные подпрограммы языка не могут использоваться в качестве фактических параметров подпрограмм.
Примеры заголовков функций: FUNCTION Plum(x,y:real):integer;
FUNCTION z(a:char; b:integer):Boolean;
и обращений к ним: u := Plum(x, x*Cos(1.12)) MOD 7; bom := z('a', Trunc(x)) AND (x>0) .
При указании типа в списке формальных параметров допускается ис-пользование только имени типа. Это значит, что если формальный параметр принадлежит перечислимому, ограниченному, структурному, ссылочному ти-пам или является подпрограммой, то надо ввести описание типа, и в заголовке использовать имя этого типа, например:
TYPE mas = ARRAY[1..10] OF real ;
...........
FUNCTION Fun(x:mas):real;
и совершенно недопустимо:
FUNCTION Fun(x:ARRAY[1..10] OF real):real .
Типы text,STRING хотя и являются структурными, но однозначно определяют свойства объекта и тоже могут использоваться в списке фор-мальных параметров.
Пример 7.2.1. Вычислить .
функция Fact(n)
главная программа
f := 1
ввод (m,n)
для k от 2 до n
f := f*k
Fact := f
печать результата
Рис.7.1.
Схемы к примеру 7.2.1.
PROGRAM Cmnfunc;
VAR m,n : integer;
cmn : longint;
FUNCTION Fact(n:integer):longint;
VAR k : integer;
f : longint;
BEGIN
f := 1;
FOR k:=2 TO n DO f:=f*k;
Fact:=f
END; { факториал }
BEGIN
Write('Значения m,n : '); ReadLn(m,n);
cmn:=Fact(m) DIV Fact(n) DIV Fact(m-n);
WriteLn('cmn = ', cmn)
END.
Пример 7.2.2. Вычислить наибольшее значение функции на отрезке [a,b] и значение аргумента, при котором оно достигается.
PROGRAM Fmax;
VAR a,b,x,y,xmax,ymax,h : real;
k,n : integer;
FUNCTION Fun(x:real):real;
BEGIN
Max:=x*x + Exp(x)*Sin(x)
END;
BEGIN
Write('a,b = '); ReadLn(a,b);
Write('n = '); ReadLn(n);
h:=(b-a)/n;
xmax:=a;
ymax:=Fun(xmax);
FOR k:=1 TO n DO
BEGIN
x:=a+k*h;
y:=Fun(x);
IF y>ymax THEN
BEGIN
xmax:=x;
ymax:=y
END
END;
WriteLn('xmax = ',xmax, ' ymax = ',ymax)
END.
Пример 7.2.3. Имеется два массива вещественных чисел. В каждом определить наибольший элемент.
PROGRAM Maxarr;
CONST n=10;
TYPE mas=ARRAY[1..n] OF real;
VAR na,nb,k : integer;
a,b : mas;
FUNCTION Marr(b:mas; n:integer):real;
VAR mx : real;
k : integer;
BEGIN
mx:=b[1];
FOR k:=2 TO n DO
IF b[k]>mx THEN mx:=b[k];
Marr:=mx
END; { функции Marr}
{ Главная программа }
BEGIN
WriteLn('Массив a - размер элементы :');
Read(na);
FOR k:=1 TO na DO Read (a[k]);
WriteLn('Массив b - размер элементы :');
Read(nb);
FOR k:=1 TO nb DO Read (b[k]);
WriteLn('Макс для массива a = ',Marr(a,na));
WriteLn('Макс для массива b = ',Marr(b,nb));
END.
Задачи
7.2.1. Вычислить , используя определение вспомогательной функции.
7.2.2. Определить значение аргумента, при котором функция достигает наименьшего значения на отрезке [a,b].
7.2.3. Имеется два массива. Вычислить сумму элементов каждого.
7.2.4. Имеется два массива. В каждом определить количество четных элементов.
7.2.5. Имеется два массива целых чисел. Для каждого выяснить, имеется ли в нем хотя бы один отрицательный элемент, кратный 7.
7.2.6. Имеется массив строк. Выявить строку, в которой некоторый символ (задаваемый с клавиатуры) встречается чаще всех.