Подпрограммы в Турбо Паскале.
Часто в программах
возникает необходимость выполнить вычисления по одной и той же формуле, но в
разных местах программы и с различными параметрами. Было бы хорошо формулу
написать только один раз, а затем использовать ее тогда, когда это необходимо
по ходу выполнения программы. Такой подход реализовывается с помощью подпрограмм.
Подпрограмма – это самостоятельная часть программы, обладающая собственным именем.
Вызов подпрограммы осуществляется по ее имени из любого места основной
программы и любое количество раз.
Применение
подпрограмм делает программу понятнее, меньше по объему, она легче отлаживается
и быстрее выполняется. Использование подпрограмм удобно еще и потому, что
задачу легче решать по частям. Кроме того, одни и те же части (подпрограммы)
можно использовать в разных программах.
Организация подпрограмм в Турбо Паскале.
Все подпрограммы в
Турбо Паскале должны быть описаны в разделе описаний. Каждая подпрограмма
должна иметь имя, дающие возможность к ней обращаться. К подпрограмме можно
обращаться только после того, как она описана.
В Турбо Паскале
приняты два вида подпрограмм: процедуры и функции (чем они отличаются,
будет объяснено позже).
Как организуется
процедура, разберем на примере.
Предположим в
какой-то программе (например, в текстовом редакторе с именем Editor) необходимо отделять фрагменты текстов чертой, состоящей из одинаковых
символов, например, знаков «минус». Чтобы реализовать эту возможность, в
программе Editor можно создать соответствующую процедуру
(подпрограмму).
Схематически эта
программа с процедурой выглядит так (в фигурных скобках указаны пояснения):
Program editor;
…
{описание переменных основной программы}
procedure
line; {заголовок процедуры line}
var y:integer; {описание переменных процедуры}
begin {начало
процедуры}
for y:=1 to 78 do
write(‘-‘);
end;
{конец процедуры}
begin
{начало основной программы}
….
Line;
{вызов процедуры Line }
….
End.
{конец основной программы}
Из примера видно,
что процедура должна располагаться сразу после описания переменных основной
программы, перед ее началом (до служебного слова begin основной программы), то есть в конце раздела описания основной
программы. Начинается процедура с зарезервированного слова procedure, за которым, через пробел, следует имя
процедуры. Структура процедуры повторяет структуру программы
– в ней также есть заголовок, раздел описаний и сама программа.
Здесь процедура line отображает на экране строку из 78 символов «минус» (-). Но, а если
возникнет необходимость отображать не 78 символов, а другое количество, и не
«минусы», а что то другое. Тогда в основной программе, например, с помощью read(a,b), должны запрашиваться эти параметры
(количество символов – а; сам символ – b),
которые затем должны передаваться в процедуру line.
Схема такой
программы будет выглядеть так:
Program editor;
…
procedure line(n:integer;
c:char); {заголовок процедуры line}
var
y:integer;
begin {начало
процедуры}
for
y:=1 to n do
write(c);
end; {конец процедуры}
begin
{начало основной программы}
….
Read(a,b); {запрос значений
a и b}
Line(a,b);
{вызов процедуры Line }
….
End.
{конец основной программы}
Здесь, в отличие от
предыдущей программы, в заголовке процедуры заданы и сразу описаны параметры n и c, которые
далее, в процедуре, используются, как обычные переменные. Их называют формальными
параметрами.
Также в основной
программе изменился и вызов процедуры Line(a,b) – добавлены
переменные a и b. Они называются фактическими параметрами.
Эти два изменения
необходимы для передачи значений переменных a и b (которые
вводятся с помощью Read(a,b)) из основной программы в процедуру.
Итак, при вызове
процедуры Line значения переменных a
и b (которые здесь
являются фактическими параметрами) передаются внутрь процедуры с помощью
формальных параметров n и c.
В свою очередь
фактические параметры бывают двух типов:
§
Параметры-значения;
§
Параметры-переменные.
Чем они
отличаются?
Параметры-значения передают свое значение подпрограмме и после ее завершения сохраняют
свое значение, даже если оно было изменено в подпрограмме.
Параметры-переменные передают свое значение подпрограмме, могут в ходе ее выполнения
изменить свое значение и сохраняют изменения при выходе из подпрограммы.
Как отличают
их в программе?
В описание
подпрограммы, перед параметрами-переменными стоит ключевое слово var.
Например:
Procedure proc
(x:integer; var y:real).
Здесь параметр y это параметр-переменная, а х – параметр-значение.
Другой
пример.
Program proba;
….
Procedure proc
(x:integer;var y:real);
Begin
Y:=x*5;
End;
Begin
а:=1;
b:=50;
Proc(a,b);
End.
|
|
Сравним два фрагмента программы:
Program proba;
….
Procedure proc
(x:integer; y:real);
Begin
Y:=x*5;
End;
Begin
а:=1;
b:=50;
Proc(a,b);
End.
Отличаются эти две
программы строкой заголовка процедуры: Procedure proc (x:integer; y:real); и Procedure proc (x:integer;var y:real);. В первом случае у является
параметром-значением, а во втором - параметром-переменной (так как перед
у
записан var).
После выполнения
первой программы, значения a и b в основной программе останутся такими же (а=1, b=50).
После выполнения второй программы, значение а останется таким же, а
значение b изменится (b=5),
так как оно передается в процедуру, как параметр-переменная и там меняет свое
значение.
Описание функций в Паскале.
Помимо процедур,
Турбо Паскале применяются подпрограммы и иного вида – функции.
Разберем их на
примере.
Задача:
В Турбо Паскале не
существует стандартной функции, которая вычисляет заданную степень заданного
числа. Однако ничто не мешает создать такую функцию самостоятельно и использовать
ее в вычислениях степени числа (пусть число и его степень являются целыми числами).
Program example1;
Var y:longint;
a,b:integer;
Function stepen
(c,n:integer):longint;
Var i:integer;
z:longint;
Begin
z:=1;
For i:=1 to n do
z:=z*c;
stepen:=z;
End;
Begin
Writeln(‘введите число и его степень’);
Readln(a,b);
y:=stepen(a,b);
Writeln(y);
End.
Из примера видно,
что запись функции аналогична записи процедуры. Но небольшие различия все-таки
имеются. Описание функции начинается со служебного слова function. За ним через пробел следует имя функции; далее в скобках – перечень
формальных параметров; затем после двоеточия указывается тип значения,
возвращаемого функцией.
Обращения к функции
из основной программы, задание параметров функции – все это организуется так
же, как и при работе с процедурами.
Чем
отличается функция от процедуры?
§
В результате использования функции, возвращается
некоторое значение. Тип возвращаемого значения указывается в описании функции
(в заголовке). Если имя процедуры используется только для ее вызова, то с
именем функции ассоциируется некоторое возвращаемое значение.
§
Поскольку функция должна возвращать некоторое
значение, в ней обязательно должен присутствовать оператор присваивания, в
правой части которого указано имя функции (в примере выше - это stepen:=z;).
Когда лучше использовать процедуры и когда функции? Это зависит от
конкретного случая. Если подпрограмма вычисляет единственный результат, ее
можно реализовать как функцию, Если же от подпрограммы требуется вычислить
несколько значений, ее лучше оформить в виде процедуры.
Для примера
разберем еще одну задачу.
Задача: Найти значение у=35 – 43 +164
Program example2;
Var y:longint;
Function stepen
(c,n:integer):longint;
Var i:integer; z:longint;
Begin
z:=1;
For i:=1 to n do
z:=z*c;
stepen:=z;
End;
Begin
Y:=stepen(3,5) - stepen(4,3) +
stepen(16,4);
Writeln(‘y=’y);
End.
В данной программе,
при вызове функции, в роли фактических параметров выступают константы (числа 3
и 5, 4 и 3, 16 и 4)
Вообще, в качестве
фактических параметров-значений могут быть не только переменные, но и константы
(например, какие-нибудь числа, как в предыдущем случае). Но фактические
параметры-переменные могут быть только переменные.
Задачи:
1.
Найти значение выражения (примените функцию
определения факториала)
2*5!+3*8!
2.
Даны два натуральных числа. Выяснить, в каком из
них сумма цифр больше (примените функцию для расчета количества цифр
натурального числа).
Рекурсия.
В практике часто
встречаются случаи, когда удобно было бы, чтобы процедура или функция вызывала
сама себя. Такой прием называется рекурсией.
Итак, если
программа (или функция) обращается сама к себе как к подпрограмме (или функции)
непосредственно или через цепочку подпрограмм, то это называется рекурсией. А
такие программы (или функции) называются рекурсивными.
Разберем пример:
Составить программу
определения факториала натурального числа.
Для решения этой
задачи можно применить рекурсию.
Program factorial;
Uses crt;
Var a:integer;
Function
fact(x:integer):longint;
Begin
If x=0 then fact:=1
else fact:=x*fact(x-1);
End;
Begin
Readln(a);
Writeln(fact(a));
End.
Здесь применили
рекурсивную функцию fact. Как она выполняется,
разберем при а=4:
§
из основной программы,
процедурой Writeln(fact(a)) вызывается функция fact;
§
фактический параметр 4
передается формальному параметру функции - х;
§
функция выполняется: 4 не
равен 0, тогда выполняется fact:=4* fact(3);
§
в последнем операторе
вызывается та же функция, но с параметром 3 (fact(3))
– это рекурсия;
§
в памяти ЭВМ создается
копия этой функции, но она выполняется с параметром х=3: 3
сравнивается с 0 – не равно, выполняется fact:=3*
fact(2);
§
снова, в последнем
операторе вызывается та же функция, но с параметром х=2 (fact(2));
§
в памяти создается копия
этой функции, но она выполняется уже с параметром х=2: 2 сравнивается
с 0 – не равно, выполняется fact:=2* fact(1);
§
в последнем операторе
вызывается та же функция, но с параметром 1 (fact(1));
§
в памяти создается копия
этой функции, но она выполняется уже с параметром х=1: 1 сравнивается с
0 – не равно, выполняется fact:=1* fact(0);
§
в последнем операторе
вызывается та же функция, но с параметром 0 (fact(0));
§
функция выполняется при х=0:
0 сравнивается с 0 – равно, выполняется fact:=1,
мы получили fact(0)=1;
§
теперь выполняется обратное
движение: последнее полученное значение fact(0)=1 подставляется в предыдущую копию функции - fact:=1*
fact(0), получится
fact=1 или
fact(1)=1;
§
также fact(1)=1, в fact:=2* fact(1), получится fact(2)=2;
§
также fact(2)=2, в fact:=3* fact(2), получится fact(3)=6;
§
также fact(3)=6, в fact:=4* fact(3), получится fact(4)=24;
§
все, выполнение функции
прекращается и ее результат, с помощью процедуры основной программы Writeln(fact(a)), выводится на экран.
Внимание, во всех
рекурсивных подпрограммах должно присутствовать какое-то условие прекращения
рекурсии, иначе она зациклится. В последнем случае это If x=0 then fact:=1.
Задача:
1.
Последовательность Фибоначчи образуется так: первый
и второй члены последовательности равны единицы, каждый следующий равен сумме
двух предыдущих (1, 1, 2, 3, 5, 8, 13, …). Составьте программу определения n-го члена последовательности, используя рекурсию.
Оставьте свой комментарий
Авторизуйтесь, чтобы задавать вопросы.