Обучающие курсы:

Обучение профессии "Разработчик C#" + стажировка в Mail.ru
Обучение профессии "Разработчик Python" + трудоустройство
Обучение профессии "Веб-разработчик" + стажировка в Mail.ru


Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Способы подстановки параметров

Атрибут формального параметра "способ подстановки" является характеристикой того, каким образом взаимодействуют фактический (ФКП) и формальный (ФРП) параметры. Существует несколько способов подстановки.

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

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

В качестве примера опишем в виде функции вычисление факториала итеративным методом, т.е. в соответствии с формулами N! = 1*2*3...*N (при N > 0); 0! = 1:

var i: integer; Facll, Fact2, Faet3: longinl;{oriHcaHHe переменных программы)
function Iter Fact(n: inleger):longint; var i: integer; f; longint; {описание переменных подпрограммы} begin f := 1;
for i := 2 to n do f := f * i; lterFact := f end; {function lter Fact} Следующие вызовы этой функции показывают различные задания фактического параметра, при которых значения функции lter Fact (и переменных Factl, Fact2, Fact3) будут одинаковы.
Factl := IterFact(lO); i := 10; Fact2 := IterFact(i); Fact3 := lter_Fact(5 + 5);

 

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

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

 

3.         Подстановка константы (такой формальный параметр называется параметром-константой); описатель способа подстановки в описании формального параметра задается ключевым словом const. Этот способ подстановки возможен в Турбо Паскале 7.0. Соответствующий фактический параметр (в отличие от параметра-переменной) защищается от возможных его изменений в подпрограмме. Ограничением является то, что параметр-константу нельзя передавать в другую подпрограмму в качестве
фактического параметра.

 

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

const cl = 10; с2 = 20;
type Tel = word; intl - l..cl; int2 = l..c2,
al = array[int2J of Tel; {строка матрицы}
a2 = array[intl] of al; {матрица}
procedure MaxInStr(const StrMatr: al; var MaxEl: TE1; varMMax. int2):
varj; int2;
Begin MaxEl := StrMatrfl]; {начальное значение максимального]
NMax := 1; {начальное значение номера максимального}
for j := 2 to с2 do
if StrMatr[j] > MaxEl then {нахождение макс и его номера}
begin MaxEl := StrMatr[j]; NMax := j end;
end; {procedure MaxlnStr}

 

В следующей таблице суммированы сведения о рассмотренных параметрах подпрограмм.

 

Способ подстановки

Описатель

Название ФРП

Вид ФКП

Память для ФРП

Изменение ФКП

по значению

 

параметр- значение

выражение

выделяется

нет

по ссылке

var

параметр- переменная

переменная

не выделяется

возможно

константный

const

параметр- константа

неременная

не выделяется

не допустимо

 

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

 

 

Особенности использования подпрограмм
Опережающее описание подпрограммы

Опережающим описанием подпрограммы называют описание заголовка подпрограммы с ключевым словом forward. Оно служит спецификацией подпрограммы и позволяет использовать эту подпрограмму до того, как будет дано ее полное описание. Необходимость в такой спецификации появляется в том случае, когда одна подпрограмма использует (вызывает) другую, а по правилам Турбо Паскаля использованию любого объекта должно предшествовать его описание. Задав опережающее описание подпрограммы Р1, ее можно вызывать в следующем за ним описании подпрограммы Р2, а затем описать полностью подпрограмму Р1. Следующий простой пример демонстрирует это средство.

procedure P1 (А, В: real); forward; procedure Р2(С: real); var X, Y: real;
            P1(X, Y);       
end;
procedure P1(А, В; real); var Z: real;
            P2(Z); 
end;

 

Задание дальнего типа вызова подпрограмм

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

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

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

В языке есть средство, позволяющее задать тип вызова сразу для нескольких подпрограмм. Так, вместо того, чтобы тип вызова Far указывать для каждой подпрограммы, можно "обрамить" группу таких подпрограмм директивами компилятора {$F+} и {$F-}. Это означает, что все подпрограммы группы будут скомпилированы с типом вызова Far, а последующие за ними описания подпрограмм — с типом вызова Near.
Примеры подпрограмм, описываемых с дальним типом вызова, будут приведены ниже при описании подпрограмм обобщенных алгоритмов.

 

 




 

Комментарии:


Добавить свой комментарий:


Введите значение:
 









   
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru