Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LAB3bak.DOC
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
367.62 Кб
Скачать

ЛАБОРАТОРНАЯ РАБОТА №3.

ПРОГРАММИРОВАНИЕ АЛГОРИТМОВ ПРИ ПОМОЩИ

ПРОЦЕДУР И ФУНКЦИЙ

Цель работы познакомиться с понятиями "процедура" и "функция" в языке про­граммирования Pascal, рассмотреть их сходства и различия, закрепить практические на­выки работы с системой TURBO Pascal на примере реализации алгоритмов при помощи процедур и функций

ТЕОРЕТИЧЕСКИЕ СВЕДЕНИЯ

1. Процедуры

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

Описание процедуры. Процедура оформляется аналогично программе и со­держит заголовок, разделы описаний и выполняемых операторов (тело процедуры). Синтаксис заголовка процедуры:

PROCEDURE N (p1:T1; р2:Т2; var Р1:Т1;…);

где 1) PROCEDURE ("процедура") - служебное слово,

2) N - имя процедуры;

3) pi (i = l, 2, … ) - формальные параметры-значения;

4) Pi (i = l, 2, … ) - формальные параметры-переменные;

5) Ti (i = l, 2, … ) - типы формальных параметров.

Разделы описаний процедуры подобно основной программе содержит разделы label, const, type, var и, в свою очередь, раздел процедур и функций. Раздел выполняемых операто­ров заключается в операторные скобки begin-end, причем после end в отличие от ос­новной программы становится символ ";". Процедуры должны быть описаны в главной про­грамме (или подпрограмме) перед служебным словом BEGIN основной программы (или подпрограммы) из которой она будет вызываться.

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

Формальные параметры-переменные это имена переменных указанных в заголовке после ключевого слова var. В процессе выполнении подпрограммы вместо этих переменных используются переменные вызывающей программы указанные при ее вызове (будет происходить замещение формальных переменных фактическими). В качестве фактического параметра, соответствующего формальному параметру-переменной, должна использоваться только переменная (не выражение!).

Если процедура не использует никаких значений из вызывающей программы, то список формальных параметров (параметров-значений и параметров-переменных) со скобками отсутствует.

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

N (р1, р2, …, Р1, Р2,…);

где 1) N - имя процедуры,

2) р1, р2, … - фактические имена переменных вызывающей программы, конкретные значения или выражения (используются вычисленные по ним значения).;

3) Р1, Р2, … - только фактические имена переменных вызывающей программы (только значения этих ячеек изменяются подпрограммой!!!).

Между фактическими и формальными параметрами должно быть соответствие по их (а) количеству (b) порядку следования и (с) типу.

Соответствующие фактические и формальные параметры не обязательно должны быть одинаково обозначены.

Примерами параметров-значений служат параметры X, Y и Z в процедуре Primer_1 со сле­дующим заголовком:

Procedure Primer_1 (X, Y, Z: Real; var F1, F2: Real);

Здесь фактическим параметром, соответствующим X, либо Y, либо Z, мо­жет быть значение или выражение типа Real, а – F1 или F2 должны быть обязательно индификаторами переменных типа Real.

Для параметров-значений компилятор при вызове процедуры производит сле­дующие действия (1) выделяет место в оперативной памяти для каждого формального параметра, (2) вычисляет значение фактического параметра и засылает его в ячейку, соответствующую формальному параметру, (3) выполняет тело процедуры.

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

Выполнение вызова процедуры состоит в следующем. Некоторые формальные параметры заменяются соответствующими фактическими (параметры-переменные), а другие (параметры-значения) получают значения фактических. После этого создается так называемый динамический экземпляр процедуры, который и выполняется. После вы­полнения процедуры происходит передача управления в основную программу, т е на­чинает выполняться оператор, следующий за оператором вызова процедуры

2. Функции

ПодпрограммаФункция (или просто Функция) это процедура, возвращающая результат. Оформляется аналогично процедуре. Особенности функции: она имеет только один результат выполнения, ре­зультат обозначается именем функции и возвращается (передается) в основную про­грамму.

Определение функции. Функция состоит из заголовка, раздела описаний и раздела операторов. Синтаксис заголовка функции:

FUNCTION F (P1: Т1, …, РN: ТN): Type_ F;

где 1) function ("функция") - служебное слово,

2) F - имя функции,

3) P1, .., PN - формальные параметры,

4) T1, ..., TN - типы формальных параметров,

5) Type_F - тип результата

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

Имя_функции := Результат.

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

Любые идентификаторы, введенные внутри какого-либо блока (процедуры, функ­ции) для описания переменных, констант, типов, процедур, называются локальными для данного блока. Такой блок вместе с вложенными в него модулями называют обла­стью действия этих локальных переменных, констант, типов и процедур.

Константы, переменные, типы, описанные в блоке PROGRAM, называют глобаль­ными.

В TURBO Pascal 7 0 допускается передача имени функции (или процедуры) в ка­честве фактического параметра в другую процедуру или функцию. Такой тип данных получил название процедурного типа. Для использования данной возможности необходимо придерживаться следующих правил:

1) в секции Type описать пользовательский тип как функцию (или процедуру с со­ответствующими параметрами);

2) в секции Var объявить переменную с типом функции;

3) процедуры, передаваемые в качестве параметров, должны быть обязательно откомпилированы с опцией {$F+};

4) связать переменную типа функция с пользовательской процедурой или функци­ей;

5) передать в процедуру значение этой переменной (можно передавать и непо­средственно имя процедуры или функции).

Демонстрационные примеры

Пример 1. Демонстрация использования процедуры без параметров.

PROGRAM Primer_1; (* имя головной программы *)

var a,b: Integer; (* объявление переменных головной программы *)

PROCEDURE Stars; (* заголовок процедуры Stars *)

var i: Integer; (*объявление переменных процедуры*)

BEGIN (* начало тела процедуры *)

For i :=1 to 40 do Write ('*' ); WriteLn

END; (* конец объявления процедуры Stars *)

BEGIN (* начало тела головной программы *)

WriteLn;

Stars; (* вызов процедуры Stars *)

Write (' Введите значение а ' ); ReadLn (a);

Write (' Введите значение b ' ); ReadLn (b);

Stars; (* вызов процедуры Stars *)

WriteLn (' a+b=', a+b,' a*b=',a*b,' a-b=', a-b);

Stars (* вызов процедуры Stars *)

END. (* конец головной программы*)

Пример 2. Процедурное программирование (обратите внимание на основную программу, ко­торая содержит только вызовы процедур).

PROGRAM Primer_3; (*имя головной программы*)

var x,y: Real; (*объявление переменных головной программы*)

{--------------------------------------}

PROCEDURE I_N_P_U_T (var a, b: Real); (* заголовок процедуры I_N_P_U_T *)

BEGIN (* начало тела процедуры *)

Writeln;

Write (' Введите значения двух переменных типа Real '); ReadLn (a, b)

END; (* конец объявления 1-ой процедуры *)

{--------------------------------------------------}

PROCEDURE S_W_A_P (var a, b: Real); (* заголовок процедуры S_W_A_P *)

var t: Real; (*объявление переменных процедуры*)

BEGIN (* начало тела процедуры *)

t:=a; a:=b; b:=t

END; (* конец объявления 2-ой процедуры *)

{------------------------------------------------}

PROCEDURE O_U_T_P_U_T (a, b: Real); (* заголовок процедуры O_U_T_P_U_T *)

BEGIN (* начало тела процедуры *)

WriteLn (' Результат ' ,a:7:3,' ',b:7:3)

END; (* конец объявления 3-ей процедуры *)

BEGIN (* начало тела головной программы *)

I_N_P_U_T (x,y); (* вызов процедуры I_N_P_U_T *)

S_W_A_P (x,y); (* вызов процедуры S_W_A_P *)

0_U_T_P_U_T (x, y) (* вызов процедуры 0_U_T_P_U_T *)

END. (* конец головной программы*)

Пример 3. Замечательным достижением Франсуа Виеты является введение в математику за­дачи о нахождении бесконечного произведения. Вычислить:

Заметим, что при реализации алгоритма используются функции.

PROGRAM Primer_4; {$F+} (*имя программы. Включение опции «Far»*)

type Funct = Function (X: Real):Real; (*Задание нового процедурного типа Funct *)

var Eps: Real;

F: Funct;

{------------------------------------------------------- }

function Sq2 (X: Real): Real; (* заголовок процедуры Sq2*)

BEGIN (* начало тела процедуры *)

Sq2:=Sqrt(X)

END; (* конец объявления 1-ой процедуры *)

{-------------------------------------------------------}

FUNCTION Sq3 (X:Real): Real; (* заголовок процедуры Sq3*)

BEGIN (* начало тела процедуры *)

Sq3 :=Exp (Ln (X)/3.0)

END; (* конец объявления 2-ой процедуры *)

{ --------------------------------------------------- }

FUNCTION Sq4 (X:Real): Real; (* заголовок процедуры Sq4*)

BEGIN (* начало тела процедуры *)

Sq4 :=Exp (Ln (X)/4.0)

END; (* конец объявления 3-ой процедуры *)

{--------------------------------------------------- }

function f_f_f (Eps: Real; F: Funct): Real; (* заголовок процедуры f_f_f *)

var A: Real; (*объявление переменных процедуры*)

S: Real;

r: Real;

BEGIN (* начало тела процедуры *)

A:=1.0/F(2); r:=A; S:=A;

While r<1-Eps do

begin r:=F((1+a)/2.0); A:=r; S:=S*r end;

F_F_F:=S

END; (* конец объявления 4-ой процедуры *)

BEGIN (* начало тела головной программы *)

Write ('Введите значение Eps '); ReadLn (Eps);

WriteLn ('Результат F_F_F (Eps, Sq2)); WriteLn (' Контроль ',2/PI);

WriteLn ('Результат F_F_F (Eps, Sq3));

WriteLn ('Результат F_F_F (Eps, Sq4));

END. (* конец головной программы*)

Пример 4. Измерение времени вычисления значения бесконечного произведения

PROGRAM Ramanudjan; {$E+,N+}

Uses DOS, { Необходимо для обращения к процедуре GetTime }

var Eps,A, S, r: Extended;

HourO, MinO, SecO, secOlOO, Hour1, Min1, Sec1, Sec1100: Word;

{------------------------------------------------------------}

FUNCTION WorkTime(HourO,MinO,SecO, secO1OO,

Hour1,Min1,Sec1, Sec1100: Word): Integer;

(* Функция вычисляет время, в 1/100 секунды, от начального до *)

(* конечного моментов работы программы HourO MinO SecO *)

(* SесО10О - начальное время Hour1 Min1 Sec1 Sec1100 *)

(* конечное время (часы минуть, секунды, 1/100 секунды) *)

var OldTime: Real; { Начальное время в секундах }

NewTime: Real; { Конечное время в секундах }

BEGIN

OldTime :=HourO*60*60+MinO*60+SecO+Sec0100/100;

NewTime :=Hour1*60*60+Min1*60+Sec1+Sec11OO/1OO;

WorkTime :=Round ((NewTime, 0ldTime)*lOO)

END;

BEGIN

Write ('Введите значение Eps '); ReadLn (Eps);

{ Фиксация времени начала работы программы }

GetTime (HourO, MinO, SecO, SecO1OO); A:=1.0/Sqrt(2); r:=A; S:=A;

While r<1-Eps do

begin r :=Sqrt ((1+A)/2.0); A:=r; S:=S*r end;

{ Фиксация времени окончания работы программы }

GetTime (Hour1, Мin1, Sес1, Sec11OO); WriteLn ('Результат ',S);

WriteLn ('Контроль ', 2/PI); Write ('Время работы программы ' );

WriteLn ('WorkTime (HourO, MinO,SecO,SecO1OO,

Hour1, Min1, Sec1, Sес1100),' микросек')

END.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]