Задания для самостоятельной работы

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

Разработка процедур и функций

 

Цель и задача работы: изучить работу с подпрограммами-процеду­рами и подпрограммами-функциями.

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

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

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

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

Процедурой в Турбо Паскале называется особым образом оформленный фрагмент программы, имеющий собственное имя. Упоминание этого имени в тексте программы приводит к активизации процедуры и называется её вызовом. Сразу после активизации процедуры начинают выполняться входящие в неё операторы, после выполнения последнего из них управление возвращается обратно в основную программу и выполняются операторы, стоящие непосредственно за оператором вызова процедуры (рис. 1).

Рис. 1. Взаимодействие вызывающей программы и процедуры

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

Примеры стандартных процедур: READ, READLN, WRITE, WRITELN.

Примеры стандартных функций: SIN, COS, ORD.

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

Локализация имен

При описании подпрограммы указывается её заголовок и тело. Тело подпрограммы, подобно программе, состоит из раздела описаний и раздела исполняемых операторов. В разделе описаний подпрограммы могут встретиться описания подпрограмм низшего уровня, т.е. вложенных подпрограмм (рис. 2).

Подпрограмма любого уровня может иметь множество имен констант, переменных, типов и вложенных в неё подпрограмм низшего уровня. Все имена, описанные внутри подпрограммы, локализуются в ней, т.е. они как бы «невидимы» снаружи подпрограммы.

Например, из программы (рис. 2) можно обратиться к подпрограммам А и В, но нельзя вызвать ни одну из вложенных в них процедур. Сказанное относится не только к именам подпрограммам, но и вообще к любым именам, объявленным в них – типам, константам, переменным и меткам. Все имена в пределах подпрограммы, в которой они объявлены, должны быть уникальными и не могут совпадать с именем самой подпрограммы.

Рис. 2. Пример структуры программы

При входе в подпрограмму низшего уровня становятся доступными не только объявленные в ней имена, но и сохраняется доступ ко всем именам верхнего уровня.

Образно говоря, любая подпрограмма как бы окружена полупрозрачными стенками: снаружи подпрограммы мы не видим её внутренности, но, попав в подпрограмму, можем наблюдать всё, что делается снаружи. Так, например, из подпрограммы А21 мы можем вызвать подпрограмму В, использовать имена, объявленные в основной программе, подпрограммах А и А2, и даже обратиться к ним. Любая подпрограмма может, наконец, вызвать саму себя – такой способ вызова называется рекурсией.

Подпрограмме доступны только те объекты верхнего уровня, которые описаны до описания данной подпрограммы. Эти объекты называются глобальными по отношению к подпрограмме.

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

Имена, локализованные в подпрограмме, могут совпадать с ранее объявленными глобальными именами. В этом случае считается, что локальное имя «закрывает» глобальное и делает его недоступным. Одноименные глобальные и локальные переменные – это разные переменные.

Описание подпрограммы

Заголовок процедуры имеет вид:

PROCEDURE <имя> [(<сп. ф. п.>)];

заголовок функции:

FUNCTION <имя> [(<сп. ф. п.>)]: <тип>;

Здесь <имя> – имя подпрограммы;

<сп. ф. п.> – список формальных параметров;

<тип> – тип возвращаемого функцией результата.

Список формальных параметров необязателен и может отсутствовать (на что указывают квадратные скобки). Если же он есть, то в нем должны быть перечислены имена формальных параметров и их тип, например:

procedure SB (a: real; b: integer; c: char);

Несколько следующих подряд однотипных параметров можно объединять в подсписки, например, вместо

function F (a: real; b: real): real;

можно написать проще:

function F (a, b: real): real;

 

Операторы тела подпрограммы рассматривают список формальных параметров как своеобразное расширение раздела описаний: все переменные из этого списка могут использоваться в любых выражениях внутри подпрограммы.

Пример. Возведение числа в степень. ( )

var

x,y: real;

 

function power( a, b: real): real;

begin

if a>0 then power := exp(b*ln(a))

else power := 0;

end; {function power}

 

begin

repeat

readln(x,y);

writeln( power(x,y) );

until false;

end.

 

Для вызова функции power мы просто указали её в качестве параметра при обращении к встроенной процедуре writeln. Параметры x и y в момент обращения к функции – это фактические параметры. Их значения присваиваются формальным параметрам a и b в заголовке функции, а затем производится выполнение операторов функции. Полученный результат присваивается идентификатору функции – именно он и будет возвращен как значение функции при выходе из неё.

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

Любой из формальных параметров подпрограммы может быть либо параметром-значением, либо параметром-переменной. В предыдущем примере параметры a и b определены как параметры-значения. Чтобы определить параметры как параметры-переменные, перед ними необходимо поставить зарезервированное слово var, например

function power( var a: real, b: real): real;

 

Если параметр определён как параметр-значение, то перед вызовом подпрограммы это значение вычисляется, полученный результат копируется во временную память и передается подпрограмме. Если же параметр определён как параметр-переменная, то при вызове передается сама переменная, а не её копия. Любые возможные изменения параметра-значения никак не воспринимаются вызывающей программой, так как в этом случае изменяется копия фактического параметра, в то время как изменение параметра-переменной приводит к изменению самого фактического параметра в вызывающей программе.

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

power(x, 3*sin(x)); или power(x, 3.17);

Пример.

var

a, b: integer;

 

procedure inc2( var c: integer; b: integer );

begin

c := c + c; b := b+b;

writeln(‘удвоенные :’, c:5, b:5);

end;

 

begin

a := 5; b := 7;

writeln(‘исходные :’, a:5, b:5);

inc2(a,b);

writeln(‘результат : ’, a:5, b:5);

end.

Результат выполнения программы:

исходные : 5 7

удвоенные : 10 14

результат : 10 7

 

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

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

Но! Если подпрограмма используется для обработки массива большой размерности, то при передаче такого массива как параметра-значения возникают существенные затраты времени и памяти на копирование значений массива во временную память. Эти затраты могут стать решающим доводом в пользу объявления такого параметра параметром-переменной или передачи его в качестве глобальной переменной.

Задания для самостоятельной работы

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

Задачи

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

1.1.

1.2.

1.3.

1.4.

1.5.

1.6.

1.7.

1.8.

1.9.

1.10.

1.11.

1.12.

2. Разработать функцию, осуществляющую расчёт i-го элемента заданной рекуррентной зависимости. В качестве параметра в функцию передаётся номер элемента (i>0).

2.1. ai = 2 × ai–2 + ai–1, i = 1, 2, 3, …; a1=1, a2=1.

2.2. ai = (ai–2 + ai–1) / 3, i = 1, 2, 3, …; a1=1, a2=1.

2.3. ai = ai–2 / 5 + ai–1, i = 1, 2, 3, …; a1=1, a2=1.

2.4. ai = (ai–2 + ai–1) × 2, i = 1, 2, 3, …; a1=1, a2=1.

2.5. ai = ai–2 / 7 – ai–1, i = 1, 2, 3, …; a1=56, a2=1.

2.6. ai = (ai–2 – ai–1) × 2, i = 1, 2, 3, …; a1=3, a2=1.

2.7. ai = (ai–2 – ai–1) / 2, i = 1, 2, 3, …; a1=5, a2=1.

2.8. ai = 3 × ai–22 × ai–1, i = 1, 2, 3, …; a1=2, a2=1.

2.9. ai = (2 × ai–2 + ai–1) / 3, i = 1, 2, 3, …; a1=2, a2=1.

2.10. ai = ai–2 / 4 + ai–1 , i = 1, 2, 3, …; a1=16, a2=1.

2.11. ai = ai–1 – 1 + ai–1, i = 1, 2, 3, …; a1=3, a2=5.

2.12. ai = -ai–2 /2 + ai–1 , i = 1, 2, 3, …; a1=2, a2=4.

3. Используя функцию, разработанную в п.2, разработать программу расчета суммы и произведения n первых элементов последовательности.

4. Разработать процедуру, выводящую на экран заданное количество заданных символов (в качестве параметров передаётся количество символов и сам символ (тип char)). Разработать программу, реализующую вывод на экран следующей последовательности символов в заданном формате, используя разработанную процедуру и оператор цикла.

 

4.1.   4.2.
4.3.   4.4.  
4.5. 4.6.  
4.7.   4.8.  
4.9. 4.10.  
4.11. 4.12.