Открытые параметры-массивы
Лабораторная работа № 6
Процедуры и функции
Цель работы: изучить структуру процедур и функций; области действия идентификаторов при использовании процедур и функций; способы передачи параметров. Научиться создавать программы с помощью процедур и функций.
Теоретическая часть.
Структура процедур и функций.При создании программы для решения сложной задачи выполняется декомпозиция (разделение) этой задачи на подзадачи, подзадач — на еще меньшие подзадачи и так далее, до легко программируемых элементарных подзадач.
Borland Pascal имеет различные средства для деления программы на части. На верхнем уровне деления (больших задач) — это модули, на нижнем уровне (элементарных подзадач) — это чаще всего процедуры и функции. Объектно-ориентированная методология охватывает как верхний, так и нижний уровень разработки программ.
Процедуры и функции являются важным средством в большинстве языков программирования. С их помощью можно скомпоновать группу операторов для выполнения некоторого единого действия. Процедуру/функцию можно вызывать из различных мест программы, она (функция) может возвращать вычисленные результаты, и ей можно передавать информацию, которую она использует для выполнения вычислений. Для того чтобы процедура/функция начала работу, ее нужно вызвать (активизировать).
Процедуры и функции состоят из операторов, локальных данных и внутренних процедур и функций. Структура описания процедуры и функции имеет следующий вид.
Отличия в описании функции и процедуры касаются только заголовка и раздела операторов, что отмечено непосредственно на приведенных примерах. Для демонстрации этих отличий приведем два решения одной задачи, одно из которых выполнено с помощью процедуры, а второе — с помощью функции.
Задача.Дан одномерный массив размерностью n, элементами которого являются действительные числа. Найти сумму элементов вектора.
Программа, использующая для решения процедуру имеет следующий вид.
program PSumma;
const
n = 20; { длина массива }
type
TVector = array [l..n] of Real;
var
Vector : TVector;
i : Integer;
procedure Summa (Vec : TVector; Len : Integer; Name : String );
var
i : Integer;
S : Real;
begin
S := 0;
for i := 1 to Len do
S := S + Vec[i];
Writeln('Сумма элементов вектора ', Name,' = ', S:7:2 )
end;
begin
Writeln ('Введите элементы массива: ');
for i := 1 to n do Read (Vector[i]);
Readln; { Вызов процедуры выполняется отдельным оператором!}
Summa (Vector, n, 'Vector');
end.
| |
Программа, использующая для решения функцию имеет следующий вид.
program FSumma;
const
n = 20; { длина массива }
type
TVector = array [l..n] of Real;
var
Vector : TVector;
Sum : Real;
i : Integer;
function Summa (Vec : TVector; Len : Integer ): Real;
var
i : Integer;
S : Real;
begin
S := 0;
for i := 1 to Len do
S := S + Vec[i];
Summa := S { Присваивание имени функции значения}
{ результата является обязательным}
{ оператором в теле функции}
end;
begin
Writeln ('Введите элементы массива:');
for i := 1 to n do Read (Vector[i]);
Readln;
{ Вызов функции может выполняться там, где допускается}
{ ставить выражение, в частности, в правой части оператора присваивания }
Sum := Summa ( Vector, n);
Writeln ('Сумма элементов вектора Vector = ', Sum:7:2 );
{ или непосредственно как элемент вывода процедуры Writeln}
Writeln ('Сумма элементов вектора Vector =', Summa ( Vector, n ) )
end.
| |
Область действия (сфера видимости) идентификаторов при использовании процедур и функций.Областью действия (сферой видимости) идентификатора называется часть программы, где он может быть использован.
Область действия идентификаторов определяется местом их объявления. Если идентификаторы допускается использовать только в рамках одной процедуры или функции, то такие идентификаторы называются локальными. Если действие идентификаторов распространяется на несколько вложенных (не менее одной) процедур и/или функций, то такие идентификаторы называются глобальными.
Заметим, что понятия "глобальные" и "локальные" следует понимать относительно — по отношению к конкретной процедуре или функции.
Продемонстрируем это следующим примером.
В данном примере А0, В0, С0 будут глобальными для всех процедур и функций, используемых в программе.
А1, В1, С1 будут глобальными для всех процедур ифункций, описанных внутри процедуры Р1 (в данном примере для процедуры Р2), и одновременно локальными для самой процедуры Р1.
Данные А2, В2, С2, объявленные в самой внутренней процедуре Р2, будут только локальными.
Сформулируем правила определения области действия для идентификаторов процедур и функций:
♦действуют все идентификаторы, определенные внутри процедуры/функции;
♦действуют все идентификаторы окружающего контекста, если их имена отличаются от имен, объявленных внутри процедуры/функции;
♦локальные идентификаторы процедуры/функции во внешнем окружении действовать не будут никогда;
♦в случае совпадения имен глобального и локального идентификаторов действовать будет только внутренний локальный идентификатор.
Если первых три правила поясняются рассмотренным примером, то для пояснения четвертого приведем еще один пример.
То есть, объявление во внутренней процедуре данных с идентификаторами, совпадающих по имени с данными внешних процедур, отменяет действие внешних идентификаторов и вводит свои локальные описания, независимо от того совпадают они по типу, или нет.
Локальные данные создаются при вызове процедуры/функции и существуют только во время ее выполнения. Выделение памяти для локальных данных происходит автоматически в начале выполнения процедуры/функции, а освобождение этой памяти — как только выполнение процедуры/функции заканчивается.
Операторы, расположенные в теле процедуры/функции могут обращаться к ее локальным данным (константам и переменным) и изменять их значения. Однако следует помнить, что значения локальных данных существуют пока процедура/функция работает.
Как только она заканчивается, все изменения значений локальных данных, сделанные операторами процедуры/функции, исчезнут вместе с освобождением памяти.
Классификация способов передачи параметров.При активизации процедуры/функции ей можно передавать параметры. При передаче необходимо следить, чтобы в операторе вызова были указаны все параметры, описанные в заголовке процедуры/функции.
Параметры, указываемые в заголовке процедуры/функции при ее описании, называются формальными параметрами.
Параметры, указываемые при вызове процедуры/функции, называются фактическими параметрами.
Корректность передачи параметров основывается на их порядке перечисления в заголовке процедуры и совместимости по присваиванию между соответствующими фактическими и формальными параметрами. Сфера действия имен параметров такая же, как и локальных данных.
Многие процедуры имеют несколько параметров. Задача программиста — убедиться, что параметры, которые он указывает при вызове (фактические параметры), соответствуют по смыслу формальным параметрам. Компилятор может проверить только очевидные случаи — неправильное число параметров или несовместимость типов.
Рассмотрим классификацию способов передачи параметров, реализация которых возможна в языках программирования.
Параметры различаются:
1. По механизму передачи:
а) передача по значению ( value );
б) передача по адресу (по ссылке) ( addr ) .
2. По взаимодействию вызывающей и вызываемой процедур/функций:
а) только как входной параметр ( in );
б) только как выходной параметр ( out ) ;
в) как входной, так и как выходной параметр ( inout ).
Соответственно этим различиям теоретически возможны 6 способов передачи параметров:
1)value in;
2)value out;
3)value inout;
4)addr in;
5)addr out;
6)addr inout.
Несмотря на то, что возможны шесть способов передачи параметров, в существующих языках программирования, как правило, используется не более двух-трех способов.
В Borland Pascal реализованы первый (value in), четвертый (addr in) и шестой (addrinout) способы передачи параметров.
Параметры value in.
1. При вызове процедуры/функции:
а) выполняется выделение памяти под формальные параметры и локальные данные (в стеке или в специальной области памяти для локальных данных);
б) выполняется копирование значений фактических параметров в память, выделенную для формальных параметров.
2. Во время работы процедуры/функции:
а) изменение значений формальных параметров не оказывает никакого влияния на содержимое ячеек памяти фактических параметров.
3. При окончании процедуры/функции:
а) память, выделенная под формальные параметры и локальные данные, очищается;
б) новые значения формальных параметров, полученные в процессе работы процедуры, теряются вместе с очисткой памяти.
Параметры addr in.
1. При вызове процедуры/функции:
а) выполняется выделение памяти только для локальных данных и для сохранения адресов фактических параметров (в стеке или в специальной области памяти для локальных данных);
б) выполняется копирование адресов (но не значений!) фактических параметров в выделенную для них память;
2. Во время работы процедуры/функции:
а) запрещено изменение значений формальных параметров;
б) использовать значения формальных параметров разрешено только в качестве исходных данных;
в) значения формальных параметров, используя скопированные адреса, выбираются непосредственно из памяти фактических параметров.
3. При окончании процедуры/функции:
а) влияние вызываемой процедуры/функции на вызывающую через такие параметры отсутствует;
б) память, выделенная для работы процедуры/функции очищается.
Параметры addr inout.
1. При вызове процедуры/функции:
а) выполняется выделение памяти только для локальных данных и для сохранения адресов фактических параметров (в стеке или в специальной области памяти для локальных данных),
б) выполняется копирование адресов (но не значений!) фактических параметров в выделенную для них память;
в) использовать в качестве фактических параметров константы запрещено.
2. Во время работы процедуры/функции:
а) никаких ограничений на использование параметров данного вида не накладывается;
б) изменение значений формальных параметров, используя скопированные адреса, выполняется непосредственно на ячейках памяти соответствующих фактических параметров.
3. При окончании процедуры/функции:
а) специального копирования результата не требуется, поскольку все действия с формальными параметрами выполнялись непосредственно над ячейками памяти фактических параметров;
б) память, выделенная для работы процедуры/функции, очищается.
Передача параметров в Borland Pascal.В Borland Pascal реализовано три из вышеописанных шести способов передачи параметров:
1. Параметры вида value in.
В Borland Pascal такие параметры называются параметрами-значениями. При описании заголовков процедур/функций перед идентификаторами параметров-значений дополнительные ключевые слова не ставятся.
2. Параметры вида addr inout.
В Borland Pascal такие параметры называются параметрами-переменными. При описании заголовков процедур/функций перед идентификаторами параметров-переменных ставится ключевое слово var.
3.Параметры вида addr in.
В Borland Pascal такие параметры называются параметрами-константами. При описании заголовков процедур/функций перед идентификаторами параметров-констант ставится ключевое слово const.
Первых две разновидности параметров (параметры-значения и пара метры-переменные) являются стандартными для всех реализаций и версий языка Pascal. Третья разновидность (параметры-константы) являются нововведением языка Borland (Turbo) Pascal версии 7.0.
Параметры-значения
Заголовок процедуры с описанными параметрами-значениями имеет такой вид:
procedure MyProc (Parl, Par2 : Typel; РаrЗ, Par4 : Туре2);
Механизм работы параметров-значений упрощенно можно представить такой схемой:
В качестве фактического параметра-значения могут использоваться как переменные, так и константы различных типов. Не допускаются только файловые типы и типы, опирающиеся на файловый.
Параметры-переменные
Заголовок процедуры с описанными параметрами-переменными имеет такой вид:
procedure МуРrос (var Parl, Par2 : Typel; var РаrЗ, Раr4 : Туре2);
Механизм работы параметров-переменных упрощенно можно представить такой схемой:
В качестве фактического параметра-переменной могут использоваться переменные любых типов, включая файловые и опирающиеся на файловый, но зато использование констант не допускается.
Параметры-константы
Заголовок процедуры с описанными параметрами-константами имеет такой вид:
procedure MyProc (const Parl, Раr2 : Typel; const РаrЗ, Раr4 : Туре2 );
Механизм работы параметров-констант упрощенно можно представить такой схемой:
В качестве фактического параметра-константы могут использоваться как переменные, так и константы различных типов. Не допускаются только файловые типы и типы, опирающиеся на файловый. Кроме того, запрещается выполнять присваивания формальным параметрам-константам и формальные параметры-константы не могут передаваться в качестве фактических параметров другим процедурам/функциям.
Параметры-константы целесообразно использовать в случаях, если требуется передавать структуры данных, занимающие большой размер памяти, но изменять исходные значения параметров с алгоритмической точки зрения недопустимо. В результате экономно используется оперативная память и одновременно гарантируется целостность исходных данных.
Бестиповые параметры
Бестиповые параметры могут передаваться только по адресу, то есть как параметры-переменные или как параметры-константы. Главной особенностью бестиповых параметров является отсутствие указания типа параметра в заголовке процедуры.
Заголовок процедуры с описанными бестиповыми параметрами при различных способах передачи имеет такой вид:
procedure МуРrос (var Parl, Par2; const Par3,Par4 );
Однако следует помнить, что вследствие отсутствия типа, нельзя использовать бестиповые формальные параметры так же, как и типизованные. Перед использованием требуется выполнить приведение формального бестипового параметра к какому-либо типу.
Бестиповые параметры более гибки в работе, чем типизованные, но ответственность за их корректное применение возлагается на программиста, так как компилятор не может проверить совместимость типов.
Открытые параметры-массивы
В заголовке процедуры открытые параметры-массивы описываются следующим образом:
procedure OpenVector (Vector: array of TypeVector);
Открытый параметр-массив может быть параметром-значением, параметром-константой или параметром-переменной.
Передаваемые фактические параметры должны по типу совпадать с описанным типом TypeVector, но по размерности они могут быть различными: как простой переменной типа TypeVector, так и массивом любой размерности.
Гибкость при передаче массивов различной размерности получена за счет единообразия представления этих массивов как формальных параметров. Все формальные открытые параметры-массивы в рамках процедуры автоматически описываются как массивы с нулевой базой (нулевой нижней границей) указанного в заголовке типа:
array [0..N-1] of TypeVector;
где N — число элементов в фактическом параметре.
Другими словами, истинный диапазон изменения индекса фактического параметра-массива отображается в диапазон изменения индекса от 0 до N - 1.
Для определения характеристик переданного фактического параметра-массива в теле процедуры используются стандартная функция Low, которая всегда возвращает 0, стандартная функция High, которая возвращает индекс последнего элемента в формальном параметре-массиве, и функция SizeOf, которая возвращает размер фактического параметра-массива.
Открытые параметры-массивы обладают меньшей гибкостью, чем бестиповые параметры, поскольку в качестве фактических параметров могут быть массивы только одного типа.
ЗАДАНИЯ
Задача №1.Оформить решение задач (задача №1 Лабораторная работа №5) в виде подпрограммы функции. Привести решения этих задач различными способами, используя в качестве фактических параметров: параметры-значения, параметры-переменные и параметры-константы. Объясните различия.
Задача №2.Оформить решение задач (задача №2 Лабораторная работы №5) в виде подпрограммы процедуры. Привести решения этих задач различными способами, используя в качестве фактических параметров: параметры-значения, параметры-переменные и параметры-константы. Объясните различия.
Дополнительные задания
Задача №3*.С помощью рекурсий вычислить значение n!.
Задача №4*.Вывести на печать символы введенной строки ‘HELLO’ в обратном направлении с помощью рекурсий.
Не нашли, что искали? Воспользуйтесь поиском по сайту:
©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.
|