Часто в задаче требуется повторить определенную последовательность операторов в разных частях программы. Для того, чтобы описывать эту последовательность один раз, а применять многократно, в языках программирования применяются подпрограммы. Подпрограмма — автономная часть программы, выполняющая определенный алгоритм и допускающая обращение к ней из различных частей общей программы.
В языке Паскаль существует два вида подпрограмм: процедура (PROCEDURE ) и функция ( FUNCTION ). Процедуры и функции в Паскале объявляются в разделе описания после переменных.
Var PROCEDURE имя FUNCTION имя BEGIN КОД вызов процедуры по имени вызов функции по имени КОД вызов процедуры имени вызов функции имени КОД END.
Теперь несколько слов о важных понятих
Переменные,объявленные в разделе Var основной программы называются глобальными. К ним можно обращаться в любом месте основной программы, то есть между BEGIN…END
При работе с процедурами и функциями различают еще три понятия: формальные переменные, явные(фактические) и локальные.
Коротко по каждому из пунктов.
Формальные переменные — это резервация ячеек памяти для будущих значений которые будут переданы подпрограмме для её работы.
Явные(фактические) — конкретные значения переменных с которыми будет работать подпрограмма.
Локальные — существуют только в течение времени работы подпрограммы, определяются (создаются) при её вызове и исчезают после завершении работы процедуры.
Описание и вызов процедур и функций
Структура описания процедур и функций до некоторой степени похожа на структуру Паскаль-программы: у них также имеются заголовок, раздел описаний и исполняемая часть. Раздел описаний содержит те же подразделы, что и раздел описаний программы: описания констант, типов, меток, процедур, функций, перменных. Исполняемая часть содержит собственно операторы процедур.
Формат описания процедуры имеет вид:
procedure имя_процедуры (формальные параметры); var //для локальных переменных, если таковые имеются begin исполняемая часть процедуры end;
Формат описания функции:
function имя_функции (формальные параметры):тип результата; var //для локальных переменных, если таковые имеются begin исполняемая часть функции имя_функции:=результат; end;
Формальные параметры в заголовке процедур и функций записываются в виде:
var имя_параметра: имя_типа
и отделяются друг от друга точкой с запятой. Ключевое слово var может отсутствовать. Если параметры однотипны, то их имена можно перечислять через запятую, указывая общее для них имя типа. При описании параметров можно использовать только стандартные имена типов, либо имена типов, определенные с помощью команды type.Список формальных параметров может отсутствовать.
Вызов процедуры производится оператором, имеющим следующий формат:
имя_процедуры(список фактических параметров);
Список фактических параметров — это их перечисление через запятую. При вызове фактические параметры как бы подставляются вместо формальных, стоящих на тех же местах в заголовке. Таким образом происходит передача входных параметров, затем выполняются операторы исполняемой части процедуры, после чего происходит возврат в вызывающий блок. Передача выходных параметров происходит непосредственно во время работы исполняемой части.
Вызов функции в Турбо Паскаль может производиться аналогичным способом, кроме того имеется возможность осуществить вызов внутри какого-либо выражения. В частности имя функции может стоять в правой части оператора присваивания, в разделе условий оператора if и т.д.
Для передачи в вызывающий блок выходного значения функции в исполняемой части функции перед возвратом в вызывающий блок необходимо поместить следующую команду:
имя_функции := результат;
При вызове процедур и функций необходимо соблюдать следущие правила:
количество фактических параметров должно совпадать с количеством формальных; соответствующие фактические и формальные параметры должны совпадать по порядку следования и по типу. Заметим, что имена формальных и фактических параметров могут совпадать. Это не приводит к проблемам, так как соответствующие им переменные все равно будут различны из-за того, что хранятся в разных областях памяти.
А теперь рассмотрим все это на примере.
Пример 1. Вывести на екран строку из 20 звездочек 3 раза.
var n:integer; Begin n:=20; for i :=1 to n do begin write (‘ * '); end; writeln; for i :=1 to n do begin write (‘ * '); end; writeln; for i :=1 to n do begin write (‘ * '); end; writeln; End.
Не экономно, не практично и не красиво.
То же самое но с процедурой без параметров.
procedure pr; var i : integer ; //локальный параметр begin for i :=1 to 20 do write (‘ * '); writeln; end. Begin pr;//вызов процедуры по имени pr;//вызов процедуры по имени pr;//вызов процедуры по имени End.
Уже красивее. Но число 20 для звезд — не лучший вариант. Усложним задачу для вывода N звезд.
То же самое, но с процедурой с параметром.
var N:integer; procedure pr(k:integer); //формальный параметр. Ячейка памяти зарезервирована,но что там - уточним позже var i : integer ; //локальный параметр. begin for i :=1 to 20 do write (‘ * '); writeln; end. Begin Write('N=');readln(n); pr(n);//вызов процедуры по имени pr(n);//c указанием явного pr(n);//(фактического значения колличества звезд) End.
При вызове процедуры фактическое значение N присваивается формально переменной K и уже с ним работает подпрограмма.
Посложнее пример.
Найти площадь двух треугольников со сторонами А,В,С.Вывести результат на экран с двумя знаками после запятой. (Гарантируется, что треугольники существуюют).
Решение задачи «в лоб»
var a,b,c,s,p:real; //Глобальные переменные BEGIN write('A=');readln(a); write('B=');readln(b); write('C=');readln(c); p:=(a+b+c)/2; S:=sqrt(p*(p-a)*(p-b)*(p-c)); writeln('S=',s:2:2); END.
Теперь то же самое с процедурой.
var a,b,c,s,p:real; //Глобальные переменные PROCEDURE Area(st_a,st_b,st_c:real);//st_a,st_b,st_c - формальные параметры. var p:real;//докальные параметры Begin p:=(st_a+st_b+st_c)/2; S:=sqrt(p*(p-st_a)*(p-st_b)*(p-st_c)); writeln('S=',s:2:2); End; BEGIN write('A=');readln(a); write('B=');readln(b); write('C=');readln(c); Area(a,b,c);//вызов процедуры по имени и передача ей явных/фактический значений. END.
Теперь то же самое с функцией. (Функция возвращает только одно значение).
var a,b,c,s,p:real; //Глобальные переменные FUNCTION Area(st_a,st_b,st_c:real):real;//st_a,st_b,st_c - формальные параметры:тип результата. var p:real;//докальные параметры Begin p:=(st_a+st_b+st_c)/2; Area:=sqrt(p*(p-st_a)*(p-st_b)*(p-st_c)); End; BEGIN write('A=');readln(a); write('B=');readln(b); write('C=');readln(c); Writeln(Area(a,b,c):2:2);//передача функции явных/фактический значений END.
Процедура тоже может возвращать значения.
Рассмотрим использование процедуры на примере программы поиска максимума из двух целых чисел.
var x,y,m: integer; procedure MaxNumber(a,b: integer; var max: integer); begin if a>b then max:=a else max:=b; end; BEGIN write('Введите x,y '); readln(x,y); MaxNumber(x,y,m); writeln('max=',m); END.
Аналогичную задачу, но уже с использованием функций, можно решить так:
var x,y,max: integer;//max - глобальная переменная для BEGIN...END function MaxNumber(a,b: integer):integer; var max: integer;//локальная переменная видна внутри функции MaxNumber begin if a>b then max:=a else max:=b; MaxNumber := max;//Результат вычисления присваивается имени функции end; BEGIN write('Введите x,y '); readln(x,y); max := MaxNumber(x,y);//передача явных значений переменных и занесение результат функции в переменную writeln('maximum=',max); END.