Файл: Инструкция по решению некоторой задачи. Как и формулу, подпрограмму можно использовать для различных данных, передаваемых из главной программы или других подпрограмм.docx

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 06.11.2023

Просмотров: 25

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

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

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

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

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

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

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

Рассмотрим способы организации подпрограмм в Паскале.

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

Процедуры без параметров.
Описание процедуры имеет вид:

procedure имя;

{описание локальных переменных }

begin

{операторы}

end;

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

1. Рассмотрим пример вычисления наименьшего общего кратного двух натуральных чисел НОК (X, Y), которое можно вычислить, используя наибольший общий делитель этих чисел, по формуле:



Х * Y

HOK( X,Y ) = -----------------

НОД ( X,Y )

При составлении программы оформим как процедуру без параметров программу Е7 - вычисление НОД по алгоритму Евклида. Результат работы процедуры будет заносится в ячейку с именем М, переменная М описана как глобальный параметр, она используется и главной программой, и процедурой. В программе будем вычислять НОК нескольких чисел, занеся их в массив С. Этот массив формируется в разделе констант главной программы. Если данные определяются в разделе констант, они не требуют дополнительного описания в разделе переменных (var). Переменая Х сначала содержит значение первого числа, а затем ей присваивается результат - НОК двух первых чисел. Переменная Y имеет своим значение второе число из каждой пары, для которой вычисляется наименьшее общее кратное. Таким образом, при каждом шаге цикла вычисляется НОК двух чисел, первое из которых Х содержит результат предыдущего шага.

Вызов процедуры NOD вычисления наибольшего общего делителя осуществляется только по имени:

NOD;

Текст программы имеет вид:
program E24;

const c: array [1 .. 5] of integer = ( 36,54,72,18,15 );

var x, y, i, m : integer;
procedure NOD; { заголовок процедуры }

var a, b: integer; { описание локальных переменных }

begin

a := x; b := y; { сохранение исходных данных }

while a <> b do

if a > b then a := a - b

else b := b - a;

m := a {результат работы процедуры присваивается глобальной переменной }

end; { конец процедуры }
begin { начало главной программы }

x := c [ 1 ] ;

for i := 2 to 5 do

begin

y := c [ i ];

NOD; { вызов процедуры без параметров }

x := x * y div m { div - деление нацело для целочисленных данных }

end;

write (‘ НОК =‘ , x)

end. { конец главной программы }
Процедуры с параметрами. Для удобства передачи данных в процедуру и получения из нее результата используются формальные и фактические параметры. Формальные - условные обозначения в описании процедуры - описываются в ее заголовке. Фактические - с которыми требуется выполнить процедуру - перечисляются при вызове процедуры. Формальные и фактические параметры должны соответствовать по количеству, типу и порядку следования. Формальные параметры, описанные в заголовке процедуры, больше нигде не описываются. Их описание похоже на описание данных в разделе переменных и может также содержать слово var. Слово var в заголовке процедуры ставится перед теми параметрами, имена которых соответствуют выходным данным. Фактические параметры, соответствующие формальным, перед которыми стоит слово var, могут быть только именами переменных. Перед именами формальных переменных, являющимися входными данными процедуры, можно слово var не указывать. Если перед формальным параметром в заголовке процедуры нет слова var, то ему может соответствовать формальный параметр, имеющий вид выражения соответствующего типа. Если для входных данных процедуры при описании формальных параметров указано слово var, то им также соответствуют фактические параметры - имена переменных.


2. Например, процедура NOD с параметрами может иметь заголовок:

procedure NOD ( a, b: integer; var k: integer );

Вызов этой процедуры: NOD ( x, y, m);

или: NOD (36, 54, m);

Переменные в заголовке процедуры - формальные параметры, заменяемые при выполнении процедуры на конкретные значения переменных x и y или числа 36 и 54. В заголовке процедуры NOD описаны формальные параметры: a и b - входные данные, для которых находится наибольший общий делитель; k - результат работы процедуры. При вызове процедуры переменная а примет значение x, а переменная b - значение y. Результат работы процедуры при вызове попадет в ячейку с именем m, которой соответствует формальный параметр k.

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

program E25;

const c: array [1 .. 5] of integer = ( 36,54,72,18,15 );

var x, y, i, m : integer;

procedure NOD ( a, b : integer; var k : integer) ; { заголовок процедуры }

begin

while a <> b do

if a > b then a := a - b

else b := b - a;

k := a { значение переменной k -результат работы процедуры }

end; { конец процедуры }

begin { начало главной программы }

x := c [ 1 ] ;

for i := 2 to 5 do

begin

y := c [ i ];

NOD ( x, y, m); { вызов процедуры с фактическими параметрами }

x := x * y div m

end;

write (‘ НОК =‘ , x)

end. { конец главной программы }

3. Рассмотрим еще один пример использования процедуры с параметрами. Найдем с помощью процедуры среднее арифметическое, наибольший и наименьший элементы массива.

program E26;

const n = 50;

type R = array [ 1..n ] of real;

var Y:R; A, B, C : real; i : integer;

procedure Stat ( X:R; var S, min, max: real) ;

begin

S := 0 ; min := x [1]; max := x [1];

for i := 1 to n do

begin

S := S + x [ i ];

if x [ i ] < min then min := x [ i ] ;

if x [ i ] > max then max := x [ i ]

end;

S := S / n

end;

begin { главная программа }

for i := 1 to n do

read ( Y [ i ] );

Stat ( Y, A, B, C); { вызов процедуры }

writeln;

write ( ‘среднее = ‘ , A, ‘наименьшее = ‘ , B, ‘ наибольшее = ‘, C )

end.

В программе Е26 появился новый раздел описаний - раздел типов данных type. В этом разделе можно описать новый тип данных через уже известные типы, которые могут быть так же ранее описаны в данном разделе. Тип данных R - это массивы из n вещественных чисел, R - имя типа. В дальнейшем этот тип позволяет сократить описания, он используется в главной программе при описании исходного массива Y и в заголовке процедуры при описании формального параметра - массива Х.


Главная программа состоит из трех основных этапов : 1) ввода данных - массива Y; 2) вызова процедуры Stat c фактическими параметрами - массивом Y и получаемыми результатами, попадающими соответственно в ячейки А ( среднее значение), В ( наименьшее) и С (наибольшее); 3) печати результатов работы программы.

Подпрограммы-функции.

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

function имя_функции ( описание входных данных ) : тип_результата;

{описания локальных переменных }

begin

{ операторы }

имя_функции := результат;

end;

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

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

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

имя_функции (список фактических параметров)

Указатель может появиться в выражении соответствующего типа, в условиях операторов if , while и repeat после слова until, а также в операторе печати write. Примерами вызова функций являются встроенные арифметические функции, например:

write (sin(x));

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

const c: array [1 .. 5] of integer = ( 36,54,72,18,15 );

var x, y, i : integer;

function NOD ( a, b : integer) : integer; { заголовок функции }

begin

while a <> b do

if a > b then a := a - b

else b := b - a;

NOD := a {результат работы функции присваивается ее имени }

end; { конец описания функции }

begin { начало главной программы }

x := c [ 1 ] ;

for i := 2 to 5 do

begin

y := c [ i ];

x := x * y div NOD ( x, y) { вызов функции }

end;

write (‘ НОК =‘ , x)

end. { конец главной программы }

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