
- •2. Функции
- •Демонстрационные примеры
- •Задачи для самостоятельного решения
- •3. Стандартные библиотеки подпрограмм в турбо паскале Расширение возможностей Ввода- Вывода. Модуль crt
- •Переменные
- •Процедуры и функции
- •4. Модуль Graph. Графический режим
- •Простейшие графические процедуры и функции
- •5. Численное решение алгебраических и трансцендентных уравнений
- •Метод секущих
- •Пример решения уравнения
- •Задание №1
- •Задание №3
ЛАБОРАТОРНАЯ РАБОТА №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.