Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
6. Подпрограммы.doc
Скачиваний:
7
Добавлен:
10.09.2019
Размер:
73.73 Кб
Скачать

Лабораторная работа №6. Подпрограммы языка Pascal

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

Подпрограммы решают три важные задачи:

  1. избавляют от необходимости многократно повторять в тексте программы аналогичные фрагменты;

  2. улучшают структуру программы, облегчая ее понимание;

  3. повышают устойчивость к ошибкам программирования и непредвиденным последствиям при модификациях программы.

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

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

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

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

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

  5. Все, что Вы сделали хорошо в одной программе, Вам захочется перенести в новые. Для повторного использования таких частей лучше сразу выделять в программе полезные алгоритмы в отдельные подпрограммы.

Подпрограммы могут быть стандартными, т.е. определенными системой, и собственными, т.е. определенными программистом.

Например, модуль crt представляет собой файл, где описаны все подпрограммы. При подключении этого файла идет обращение к функциям, описанным в этом модуле. Посмотреть описание подпрограмм можно по следующему пути: Help -> Index -> Crt unit-> CRT Functions and Procedures

В Pascal есть два вида подпрограмм: процедуры и функции. Процедуры и функции, не входящие в комплект поставки Delphi (т.е. не встроенные в Delphi), называются пользовательскими подпрограммами, потому что их должен определить программист (пользователь компилятора).

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

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

  1. Количество формальных параметров должно быть равно количеству фактических параметров.

  2. Первый формальный параметр в списке соответствует первому фактическому, второй – второму и т.д.

  3. Тип каждого фактического параметра должен совпадать с типом соответствующего ему формального параметра.

  4. Имя фактического параметра никак не связано с именем соответствующего формального параметра.

  5. Необходимо строго различать способы передачи данных – по ссылке, или по значению.

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

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

procedure имя_процедуры(формальный_параметр1: mun1;

формальный_параметр2: тип2; . . .) ;

[локальные_объявления; ]

begin

[операторы; ]

end;

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

Синтаксис вызова процедуры имеет вид:

имя_процедуры (фактический_параметр1, фактический_параметр2, …);

Пример 1. Объявлена процедураWriteProc, без формальных параметров, т.е. ей никакие данные из основной программы не передаются Внутри процедуры объявляется локальная переменная local1 строкового типа, которой присваивается значение Procedure is working!!! и затем эта переменная выводится на экран. В основной программе мы просто вызываем процедуру, обращаясь к ней по имени. Т.к. нет формальных параметров в описании подпрограммы нет, то и фактических при вызове тоже не будет. После вызова управление передается процедуре, которая выводит на экран сообщение Procedure is working!!!

program proc;

uses crt;

procedure WriteProc;

var local1:string;

begin

local1:='Procedure is working!!!';

write(local1);

end;

BEGIN

clrscr;

WriteProc;

readln;

END.

Функция это подпрограмма, возвращающая одно значение, в вызывающую подпрограмму.

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

Синтаксис определения пользовательской функции имеет следующий вид:

function имя_функции(формальный_параметр1: mun1; …): тип_функции;

[локальные_объявления;]

begin

[операторы; ]

имя_функции := возвращаемое_значение;

end;

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

Синтаксис вызова функции с присвоением возвращаемого значения некоторой переменной имеет следующий вид:

имя_переменной := имя_функции (фактический_параметр1,

фактический_параметр2, . . .) ;

Пример 2. Объявлена функция WriteFunc, без формальных параметров, т.е. ей никакие данные из основной программы не передаются. Но, т.к. это функция, то она обязательна должна возвращать какое-то значение в основную программу. Указывается, что тип возвращаемого значения – строка. Возвращаемое значение – строка 'Function is working!!!' присваивается имени функции. Это значение возвращается в основную программу после вызова функции. Возвращаемое значение нужно обязательно присвоить какой-либо переменной. Для этого в начале программы объявляется глобальная (видимая во всех частях программы) переменная mystr, которой и будет присваиваться возвращаемое значение функции. Т.к. нет формальных параметров в описании подпрограммы нет, то и фактических при вызове тоже не будет. Результатом работы функции является сообщение на экране Function is working!!!

program func;

uses crt;

var mystr:string;

function WriteFunc: string;

begin

WriteFunc:='Function is working!!!';

end;

BEGIN

clrscr;

mystr:=WriteFunc;

write(mystr);

readln;

END.

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

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

Процедуре SrArifm передаются 2 формальных параметра вещественного типа – они названы x,y, можно использовать имена глобальных переменных. Затем, в процедуре объявлена локальная (т.е. видимая только в пределах этой процедуры) переменная s вещественного типа. Ей присваивается вычисляемое среднее арифметическое, которое затем выводится на экран. В основной программе процедуре SrArifm передаются 2 фактических параметра а и b – переменные, уже содержащие значения.

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

program sr_arifm;

uses crt;

var a,b,sr:real; {глобальные переменные, видимые на протяжении всего выполнения программы}

Procedure Input;

begin

writeln('Input a,b');

readln(a,b)

end;

Procedure SrArifm(x,y:real);

var s:real;

begin;

s:=(x+y)/2;

writeln('Sr=',s:2:2);

end;

Function SrArifm2 (x,y:real):real;

var s:real;

begin;

s:=(x+y)/2;

SrArifm2:=s;

end;

BEGIN

clrscr;

Input;

SrArifm(a,b);

sr:=SrArifm2(a,b);

writeln('Sr2:=',sr:2:2);

readln;

END.

Передача параметров

Передача по ссылке это передача в подпрограмму адреса (места расположения в памяти) фактического параметра. При этом подпрограмма работает непосредственно с передаваемым ей объектом.

Передача по значениюэто передача в подпрограмму значения фактического параметра, т.е. копии объекта. При этом подпрограмма работает не с объектом, а с его копией. Передача по значению предохраняет объект от изменения подпрограммой. По умолчанию в Pascal параметры передаются по значению.

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

В то же время при передаче по значению в подпрограмму передается значение переменной, т.е. подпрограмма получает доступ только к копии переменной. Изменить значение самой переменной подпрограмма не может.

Пример 4.

program param;

var

value: integer;

procedure MyProcedure (number: Integer);

begin

writeln('Executing MyProcedure. number= ',number);

number := 2*number;

writeln('Finishing MyProcedure. number= ',number);

end;

begin

value := 5;

writeln('Starting the test program. number= ',value);

MyProcedure(value);

writeln('Finishing the program. number=',value);

readln;

end.

В этом фрагменте кода параметр number передается по значению. Программа выводит следующие строки:

Starting the test program. number=5

Executing MyProcedure. number=5

Finishing MyProcedure. number=10

Finishing the program. number=5

Обратите внимание: значение value не затронуто операциями в MyProcedure.

Модифицируем этот пример. Добавив перед объявление переменной number ключевое слово var, означающее, что параметр number передается по ссылке.

procedure MyProcedure (var number: Integer);

При этом программа будет выводить следующие строки.

Starting the test program. number=5

Executing MyProcedure. number=5

Finishing MyProcedure. number=10

Finishing the program. number=10

Поскольку параметр number фактически является переменной value, процедура MyProcedure изменила значение value. В заголовке программы ключевое слово var должно предшествовать каждому параметру, передаваемому по ссылке.

Передача массивов подпрограммам

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

function Example(inArray: array[1..20] of Real): Real;

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

type

RealArray20 = array[1..20] of Real;

function Example(inArray: RealArray20): Real;

В системе Delphi допускается использование открытых индексных параметров, т.е. массивов без указания индексов. Например, оператор

procedure OpenArrayEx(inArray: array of Integer);

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

  1. Массив, объявленный как открытый индексный параметр, всегда начинается с нуля, т.е. индекс первого элемента массива всегда равен 0.

  2. Функции Low() и High() возвращают для такого массива значения 0 и длина-1. Функция SizeOf() возвращает длину фактического массива, переданного в подпрограмму.

  3. В исходном коде можно обращаться только к элементам такого массива. Обращение к целому массиву запрещено.

  4. Открытые индексные параметры не могут передаваться в процедуру SetLength(). Они могут передаваться в другие подпрограммы только как открытые индексные параметры или как нетипизированные параметры var.

  5. Передаваемая в подпрограмму переменная базового типа открытого индексного параметра внутри подпрограммы полагается массивом единичной длины.

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

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