Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
1курс_задания_к_лаб_old.doc
Скачиваний:
7
Добавлен:
19.11.2018
Размер:
1.12 Mб
Скачать

Процедуры и функции

В программах на Pascal используются подпрограммы 2-х видов: процедуры и функции. Они имеют аналогичную структуру, но несколько различаются назначением и способом их применения.

Все процедуры и функции подразделяются на:

  • стандартные или встроенные входят в стандартные библиотеки и могут вызываться по имени без предварительного описания (например, функция sin(x) или процедура Readln);

  • определенные пользователем.

Процедура – это независимая именованная часть программы, которую после однократного описания можно многократно вызывать по имени из последующих частей программы.

Структура процедуры представляет собой «программу в миниатюре»:

Procedure ИмяПроцедуры (ФормальныеПараметры:тип – их может и не быть);

{Описательная часть процедуры}

Begin

{Инструкции исполнительной части процедуры}

End;

Процедуры и функции помещаются в раздел описаний процедур и функций программы. Их вызов для выполнения записывается в разделе операторов основной программы или другой подпрограммы. Например,

ИмяПроцедуры(Фактические параметры - через запятую, если их несколько);

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

Для принудительного выхода из процедуры в ее теле используется оператор Exit.

Использование процедур позволяет упростить внесение изменений в повторяющиеся фрагменты, т.к. исправления делаются 1 раз в процедуре, а не много раз в программе.

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

Пример: процедура, которая из заданной суммы денег (действительное число) выделяет рубли и копейки (2 целых числа). Результат сохраняется в 2-х переменных, которые через параметры передаются в программу.

Procedure RubKop(summa:real; var rub, kop: integer);

Begin

rub:=trunk(summa);

kop:=round((summa-rub)*100);

End;

Обратиться к этой процедуре можно, например, так:

RubKoop(157.25,r,k);

Здесь r и k – переменные целого типа (имена, кстати, могут быть любые), в которые будут занесены результаты.

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

  • Формальных и фактических параметров должно быть одинаковое количество;

  • Порядок следования формальных и фактических параметров должен быть один и тот же;

  • Тип фактического параметра должен быть совместим с типом формального параметра.

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

Функция пользователя во всем аналогична процедуре, за исключением 2-х отличий:

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

  • имя функции может входить в выражение как операнд.

Описание функции:

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

{Описательная часть функции}

Begin

{Инструкции исполнительской части функции}

…..

ИмяФункции:=Результат;

End;

! В разделе операторов функции должен быть хотя бы 1 оператор, который присваивает ее имени значение результата работы функции. Если такой оператор отсутствует, то значение, возвращаемое функцией, не определено (хотя компилятор не выдает сообщения об ошибке, но результат работы будет неправильный).

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

Пример: возведение любого числа в целую неотрицательную степень.

Function Stepen(x:real; n:byte):real;

{Возводим число x в целую неотрицательную степень n}

Var

i:integer;

res:real;

Begin

res:=1;

For i:=1 to n do res:=res*x;

Stepen:=res; {т.е. не забыли присвоить результат функции}

End;

{Основная программа}

Begin

….

Writeln(Stepen(2,10));

y:=15;

B:=Stepen(3,5)+Stepen(y,5);

….

End.

ПРИМЕР: Использование функции для решения квадратного уравнения.

Function Kvadrur(a,b,c:real; var x1,x2 : real):integer;

{функция для реш-я квадратного ур-я}

{a,b,c – коэффициенты уравнения (оформлены как параметры-значения)}

{x1,x2 – корни уравнения (оформлены как параметры-переменные)}

{значение самой функции – кол-во корней или -1, если а=0}

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;

x1,x2:real;

BEGIN

Writeln(‘Введите коэффициенты a,b,c’);

Readln(a,b,c);

Case kvadrur(a,b,c,x1,x2) of

-1: writeln(‘Уравнение не квадратное’);

0: writeln(‘Уравнение не имеет вещественных корней’);

1: writeln(‘x=’,x1:7:3,‘Корни одинаковы’);

2: writeln(‘x1=’,x1:7:3,‘x2=’,x2:7:3);

End;

Readln;

END.

! Комментарий к программе: обратите внимание, что функция Kvadrur возвращает не 1, а 3 результата, причем один из них (кол-во корней) передается как результат функции через ее имя и используется в операторе Case, а переменные x1 и x2 передаются как параметры-переменные.

НЕМНОГО О РАСПРЕДЕЛЕНИИ ПАМЯТИ:

Все объекты (метки, константы, типы, переменные, процедуры и функции), которые описаны в теле подпрограмм, являются локальными объектами, т.е. доступны только в пределах этой подпрограммы и недоступны вызывающей программе. Как выделяется память для данных подпрограммы?

При запуске любой программы для нее формируется специальная область памяти – программный стек, которая используется для хранения локальных переменных подпрограмм, которые помещаются в стек непосредственно при вызове подпрограммы.

Параметры подпрограммы также помещаются в стек, причем для параметров-значений в стек помещается само значение, для параметров – переменных – адрес фактического параметра, в котором хранится значение. Кроме того, в стек помещается точка возврата, т.е. адрес инструкции вызывающей программ, к которой нужно вернуться после окончания работы подпрограммы.

Как только подпрограмма закончит работу, вся память, отведенная для нее в стеке, считается свободной и может использоваться данными других подпрограмм. Так обеспечивается независимость подпрограмм друг от друга и от основной программы.

Все объекты, описанные в вызывающей программе, называются глобальными. Память под них выделяется при компиляции программы, и эта часть памяти называется сегментом данных. Глобальные переменные находятся в сегменте данных от начала до конца работы программы, поэтому ими можно пользоваться и в программе, и во всех подпрограммах, к которым обращается программа.

Следует знать:

  • обмен данными между программой и подпрограммой может производиться не только через параметры, но и через глобальные переменные;

  • если одно и то же имя определено и в программе, и в подпрограмме, то внутри подпрограммы глобальный объект недоступен, т.е. он как бы экранируется локальным объектом с тем же именем;

  • если одно и то же имя определено в нескольких подпрограммах одной программы, то в каждой подпрограмме это будут разные локальные объекты, не зависящие друг от друга (если только подпрограммы не вложены одна в другую).

ПРИМЕР:

Var

a,b,c,d : Integer; {глобальные переменные}

Procedure P(x:integer; var y:integer);

Var

c: Integer; {локальные переменные}

Begin {тело процедуры}

c:=1;

d:=1;

x:=1;

y:=1;

Writeln(x:3,y:3,c:3,d:3);

End;

Begin {Тело основной программы}

a:=0;

b:=0;

c:=0;

d:=0;

p(a,b);

Writeln(a:3,b:3,c:3,d:3);

End.

При выполнении эта программа напечатает строки:

1 1 1 1

0 1 0 1 - Разберитесь самостоятельно!!

Комментарий к программе: x – формальный параметр-значение, которому соответствует фактический параметр a=0. В процедуре его значение заменится на 1, после чего результат будет напечатан. На переменной a это никак не отразится, и после выполнения процедуры a по-прежнему будет равно нулю. y – параметр-переменная, поэтому при выполнении процедуры вместо y действия будут проводиться с переменной b, которая получит значение 1. c – локальная переменная, которая маскирует глобальную переменную с основной программы. d – глобальная переменная.