Студопедия.Орг Главная | Случайная страница | Контакты | Мы поможем в написании вашей работы!  
 

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



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

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

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

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

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

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

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

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


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

Procedure <Имя_Процедуры> [ (< Список_Параметров >) ];

Пояснение: квадратные скобки в описании показывают необязательность этой части оператора

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

Procedure <Имя_Процедуры> (ПараметрЗначение1: ТипЗначение1;

ПараметрЗначение2: ТипЗначение2;

Var ПараметрПеременная1:ТипПременная1;

Var ПараметрПеременная2:ТипПеременная2;

...);


Label <Метки_Используемые_в_Процедуре>

Const <Константы_Используемые_в_Процедуре>

Type <Типы_Используемые_в_Процедуре> Декларативная

Var <Переменные_Используемые_в_Процедуре> часть

процедуры

<Описание вложенных процедур и (или) функций>

Procedure...

Function...

Begin

< Тело процедуры > Исполнительная часть процедуры

End; {Имя процедуры}

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

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

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

Таким образом, при описании процедуры определяются все объекты, с которыми она работает, и действия над этими объектами. Описание процедуры, расположенное в декларативной части программы, само по себе никакого действия не производит.

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

<Имя_Процедуры> [ (< Список_Параметров >) ];

Пояснение: квадратные скобки в описании показывают необязательность этой части оператора

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

Например, необходимо написать процедуру вычисления корней квадратного уравнения ax2 + bx + c = 0. Заголовок этой процедуры будет выглядеть следующим образом:

Procedure Roots (A,B,C: Real; Var Root1,Root2: Real);

где A, B и C – коэффициенты квадратного уравнения, Root1 и Root2 – корни этого уравнения.

Вызов процедуры осуществляется по ее имени.

Roots (A, B, C, Root1, Root2);

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

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

Procedure Title; и вызвать по имени Title.

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

Все сказанное ранее о процедурах справедливо и для функций. Вместе с тем имеется ряд отличий. Одно из них чисто внешнее: заголовок начинается с зарезервированного слова Function.

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


Как и у процедуры, список параметров функции может быть пустым, в этом случае отсутствуют и сами скобки.

Function <Имя_Функции> [ (< Список_Параметров >) ]:

<Тип_Результата>;

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

Другие отличия более существенны:

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

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

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

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

<Переменная_Типа_Результат_Функции>

:= <Имя_Функции> [ (< Список_Параметров >) ];

Пояснение: квадратные скобки в описании показывают необязательность этой части оператора

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

{====== Среднее арифметическое элементов вектора ======} Сonst
n_max = 50; { Количество элементов вектора }
Type  
Vector = Array[1..n_max] of Real;  
Var b: Vector;  
Number: Byte; { Количество элементов }
Aver: Real; { Среднее арифметическое }
Function Average {=== Вычисление среднего ======} {== арифметического вектора ===}
(n: Byte; Var a: Vector): Real; { Заданное количество элементов } { Вектор }
Var I: Byte; { Параметр цикла }
Sum: Real; {Сумма элементов вектора }
Begin  
Sum:= 0;  
For i:= 1 to n do  
Sum:= Sum + a[i]; { Нахождение суммы вектора }
Average:= Sum / n; { Нахождение среднего арифметического} { Возвращение результата через имя }
End { Average };  
Begin { Главный begin программы }
Readln (Number); { Ввод рабочего размера вектора }
For i:= 1 to Number do Readln (b[i]); { Ввод элементов вектора }
{======== Первый способ получения результата ==========}
Aver:= Average (Number, b); { Активация функции } { Сохранение результата в } { переменную Aver }
Write (‘Среднее арифметическое ’, Number); Write (‘ элементов вектора = ’, Aver:12:4);
  {========= Второй способ получения результата =========}
Write (‘Среднее арифметическое ’, Number); Write (‘ элементов вектора =’,Average(Number,b):12:4);
{ Результат вычислен временно и нигде не сохранен!!! }
End.
           

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

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

Локальные и глобальные параметры

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

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

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

Самый внешний (1), определяемый программой блок, содержит внутри себя подблоки (2, 3, 4, 5), реализованные с различным уровнем вложенности. При этом объекты, описанные внутри 2, 4 и 5 блоков, являются локальными в своем блоке и недоступны внешним блокам. Объекты блока 3 являются с одной стороны локальными в своем блоке и глобальными для блоков 4 и 5.


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

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

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

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

Передаваемые параметры процедур и функций

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

Формальные параметры – это абстрактные объекты, по отношению к которым выполняется процедура или функция. Формальные параметры – это параметры, используемые при описании процедуры или функции.

Procedure <Имя_Процедуры> [ (< Формальные_Параметры >) ];

В отличие от них фактические параметры – это конкретные объекты, с которыми работает процедура или функция. Фактические параметры находятся в списке параметров при вызове.

<Имя_Процедуры> [ (< Фактические_Параметры >) ];

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

Типы фактических параметров должны соответствовать типам формальных параметров Количество фактических параметров при обращении к подпрограмме должно совпадать с количеством формальных параметров

Соответствие между фактическими и формальными параметрами устанавливается по их номерам в списке слева направо: первому слева формальному параметру ставится в соответствие первый слева фактический параметр, второму слева формальному – второй слева фактический и т. д

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

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

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

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

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

входные - через которые процедура получает исходные данные;

выходные - через которые процедура отдает результаты;

возвратные - через которые процедура получает данные и отдает результаты.

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

В языке Паскаль различают формальные параметры четырех видов:

параметры-значения;

параметры-переменные;

параметры-процедуры;

параметры-функции.

Параметры-значения

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

При вызове процедуры (функции) на место параметра-значения могут подставляться фактические параметры в виде констант, переменных, стандартных функций, арифметических выражений. Рассмотрим это на примере процедуры нахождения корней квадратного уравнения, где A, B, C - коэффициенты квадратного уравнения, Root1,Root2 - его корни.

Procedure Roots (A,B,C:Real; Var Root1,Root2:Real);

константы

Roots (ConstA, ConstB, ConstC, Root1, Root2);

конкретные числовые значения

Roots (15, 44, 371, Root1, Root2);

переменные

Roots (A1, B1, C1, Root1, Root2);

стандартные математические или «библиотечные» функции

Roots (Sqr(A), Abs(B), Sqrt(C), Root1, Root2);

арифметические выражения

Roots (A+Sqr(В), B+А, 4-Sqr(C), Root1, Root2);

При этом необходимо помнить о соответствии типов формальных и фактических параметров.

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

Параметры-переменные

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

Параметр-переменная используется для представления результатов работы процедуры, т.е. может быть выходным или возвратным параметром.

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

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

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

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

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

Описание его глобально, а использование внутри процедуры может привести к непредсказуемым результатам

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

Лабораторная работа №11 (2 часа)

Тема: Составление и запись алгоритмов вычислительных процессов с использованием подпрограмм. Компиляция и тестирование программы.

Цель: Приобрести навыки составления и записи алгоритмов вычислительных процессов с использованием подпрограмм. Проведения компиляции и тестирования программы.

Задание: Разработатьалгоритм решения задачи согласно варианту, представить его в виде программы на языке программирования Turbo Pascal.

Вариант 1. Найти значение переменной S =. Для вычисления функции f составить процедуру-функцию с параметром, одномерным массивом чисел, заданную условиями:

1, если

f(x1, x2, …, xn) =

в остальных случаях.

Вариант 2. Найти значение переменной S = ln(sin(f - 5f 3 )). Для вычисления функции f составить процедуру-функцию с параметром, одномерным массивом чисел, заданную условиями:

0, если ;

f(x1, x2, …, xn) =

в остальных случаях;

Вариант 3. Найти значение переменной . Для вычисления функции f составить процедуру-функцию с параметром, одномерным массивом чисел, заданную условиями:

0, если x1 > x2 > … > xn;

f (x1, x2, …, xn, x1, x2, …, xn) =

в остальных случаях;

Вариант 4. Найти значение переменной S = . Для вычисления функции f составить процедуру-функцию с параметром, одномерным массивом чисел, заданную условиями:

1, если;

f(x1, x2, …, xn) =

, в остальных случаях;

Вариант 5. Найти значение переменной . Для вычисления функции f составить процедуру-функцию с параметром, одномерным массивом чисел, заданную условиями:

0, если x1 > x2 > … > xn;

f (x1, x2, …, xn) =

, в остальных случаях;

Вариант 6. Найти значение переменной S = . Для вычисления функции f составить процедуру-функцию с параметром, одномерным массивом чисел, заданную условиями:

, если

f (x1, x2, …, xn, y1, y2, …, yn) =

в остальных случаях;

Вариант 7. Найти значение переменной S = ln(sin(f - 5f3)). Для вычисления функции f составить процедуру-функцию с параметром, одномерным массивом чисел, заданную условиями:

, если ;

f (x1, x2, …, xn, y1, y2, …, yn) =

1, в остальных случаях;

Вариант 8. Найти значение переменной S = . Для вычисления функции f составить процедуру-функцию с параметром, одномерным массивом чисел, заданную условиями:

, если;

f (x1, x2, …, xn, y1, y2, …, yn) =

в остальных случаях;

Лабораторная работа №12 (2 часа)

Тема: Разработка алгоритмов с использованием записей в виде программы.

Цель: Приобрести навыки работы с процедурами и функциями обработки переменных типа «запись».

Задание: Разработатьалгоритм решения задачи согласно варианту, представить его в виде программы на языке программирования Turbo Pascal.

Вариант 1. База данных “Библиотека содержит таблицу с полями: Ф. И. О., домашний адрес, дата сдачи книги. Вывести содержимое базы в виде таблицы, разработать процедуры редактирования таблицы (удаление, вставка, изменение поля некоторой записи).

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

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

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

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

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

Вариант 7. Заполнить массив десяти элементов записями вида: №, Ф. И. О., книга, количество экземпляров. Вывести содержимое массива в виде таблицы, разработать процедуры редактирования таблицы (удаление, вставка, изменение поля некоторой записи).





Дата публикования: 2015-02-22; Прочитано: 267 | Нарушение авторского права страницы | Мы поможем в написании вашей работы!



studopedia.org - Студопедия.Орг - 2014-2024 год. Студопедия не является автором материалов, которые размещены. Но предоставляет возможность бесплатного использования (0.027 с)...