Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Формальные и фактические параметры




РЕКУРСИЯ

Допускается, что подпрограмма может вызывать саму себя. Эта возмож­ность связана с тем, что при каждом новом обращении к подпрограмме, па­раметры, которые она использует, заносятся в стек. Причем, параметры из стека удаляются при выходе из подпрограммы. Таким образом, в стеке со­храняются все параметры от предыдущих вызовов. В ряде случаев рекур­сивное оформление подпрограммы более компактное и эффективное. Но не следует забывать, что существует опасность переполнения стека. Классиче­ским примером рекурсии является рекурсивная формула вычисления факто­риала

m=N(N-1)! (N-1)1 = (N-1)(N-2)! и т.д.

Напишем подпрограмму вычисления факториала по рекурсивной фор­муле.

Function Factorial(N: byte): Cardinal; Begin

If N in [0,1] then Result:=l

Else Factorial:=N*Factorial(N-l); End;.

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

Формальные параметры задаются при объявлении подпрограммы, фактические параметры указываются при выполнении расчетов, т.е. при вызове подпрограммы. Фактические параметры должны быть идентичных типов с формальными. Их число должно быть равно числу формальных па­раметров, должен совпадать и порядок следования фактических параметров с порядком записи формальных. Механизм передачи данных через формаль­ные параметры реализуется с использованием специальной области памяти -стека. По умолчанию размер стека установлен 16384 байта. Можно изменить объем стека в настройках среды Delphi.

ПАРАМЕТРЫ-ЗНАЧЕНИЯ

В этом случае для передаваемого фактического параметра создается ко­пия в стеке. Синтаксис записи, например, таков: Function FF(a,b:Real;...):...; (пример приведенной выше подпрограммы содержит этот тип пара­метров). На месте параметра-значения при вызове подпрограммы может сто­ять выражение, совместимое по присваиванию с формальным параметром.


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

ПАРАМЕТРЫ-ПЕРЕМЕННЫЕ

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

ПАРАМЕТРЫ-КОНСТАНТЫ

Параметры-константы синтаксически введены для того, чтобы ключевое слово var сохранить за выходным параметром и в то же время чтобы вход­ной параметр мог передаваться по адресу. Синтаксис записи этих парамет­ров таков: Procedure PP(const a:real;...); (пример процедуры, приве­денной выше, содержит этот тип параметров). В данном случае простые пе­ременные передаются как копии, а, например, массивы и строки - по адресу. Компилятор сам определяет, что передавать по адресу, а что как копию. Из­менить параметры-константы внутри подпрограммы нельзя. Таким образом, входные параметры могут передаваться в подпрограмму как параметры-константы. Вместо параметров-констант можно подставлять выражения, как и для параметров-значений.

ПАРАМЕТРЫ БЕЗ ТИПА

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

Function MMax(var a): Integer; Type Vect = array of integer;


Var i: byte; Begin

Result:= Vect(a)[0];

For i:= 1 to High<Vect(a)) do

If Result < Vect(a) [i] then Result:= Vect(a) [i]; End;.

В качестве фактического параметра в данном случае можно использо­вать любой одномерный динамический массив целых чисел, размерность этого массива может быть любая. Пусть требуется найти с помощью этой функции максимальный элемент для вектора В, состоящего из 20 элементов. Сначала объявим этот вектор и переменную Y, в которую запишем резуль­тат: Var в: array of integer; Y: integer;. Далее надо определить массив, предварительно выделив для него память: setLength(B,20);. Те­перь запишем вызов функции Y:=Mmax(B),-.

МАССИВЫ ОТКРЫТОГО ТИПА

В подпрограммах нельзя объявлять формальный параметр как статиче­ский массив в виде array [...] of..., так как он не будет идентичен ни од­ному фактическому параметру. Если все же необходимо обмениваться с под­программой данными в виде статических массивов, то предварительно их надо типизировать, например, Type vekt = array [1..20] of real;...procedure sum (const V:Vekt;...).

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

Function Mmax(const Mas: array of Integer): Integer;

Var I: Byte; Begin

Result:= Mas[0];

For i:= 1 to High(Mas) do

If Result < Mas[i] then Result:= Mas[i]; End;.

Если формальный параметр представляет собой открытый массив, то в качестве фактического параметра можно использовать конструктор масси­ва. Конструктор массива разрешается применять, если открытый массив за­дан в виде параметра-константы, как в предыдущей функции Мшах. Конст­руктор открытого массива по синтаксису записи совпадает с конструктором множества. Пусть заданы три значения: а, 15, b + с, где а,Ь,с- переменные.


Найти среди них максимум с помощью подпрограммы Mmax и результат записать в Y-y:= ММах([а, 15, Ь + с]);.

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

ПАРАМЕТРЫ ПО УМОЛЧАНИЮ

Часто при вызове подпрограммы в нее нужно передавать параметры, имеющие некоторое заданное значение. Например, получить распределение случайных чисел, зависящее от многих параметров, но при одном заданном k = 5 или к = 9, где к - некоторая характеристика, остальные параметры из­меняются одинаково. Заменить такие параметры, как к, на константы нельзя - все же они иногда меняются. Эта проблема решается введением парамет­ров по умолчанию. Например, запишем функцию для вычисления распреде­ления Гаусса:

 

Здесь х - случайная величина, заданная в диапазоне- от а до b с шагом h; m=(a+b)/2; a - параметр, по умолчанию равный 1 (но иногда требуется за­дать значение, например 0,5 или 2).

Function Gaussa(x, m: real; sigma: real=1.0): real;

Begin

Result:=exp{-sqr(x-m)/(2*sqr(sigma)))/

(sqrt(2*:c) *sigma);

End;

При выполнении расчетов можно записать так: Y: = Gaussa(x, (a+b)/2) опуская параметр sigma, или так: Y: = Gaussa(x,(a+b)/2,2.0);.

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

Func­tion MyFF(x:byte= 1; y:byte= 1; z:byte= 1):byte; можно записать Так: A:=MyFF(2,2,2);, A:=MyFF<2,2);, A:=MyFF(2);, A:=MyFF;, a TSK Записывать нельзя: A:=MyFF(, 2, 2); A:=MyFF(2,, 2);.

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


 

 



Поделиться с друзьями:


Дата добавления: 2014-12-29; Просмотров: 1966; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.064 сек.