В.Г. Абрамов, Н.П. Трифонов, Г.Н. Трифонова - Введение в язык Паскаль (1107618), страница 36
Текст из файла (страница 36)
При этом соответствие между фактическими и формальными параметрами устанавливается путем их сопоставления в обоих списках: первый по порядку фактический параметр соответствует первому формальному параметру, второй фактический параметр —второму формальному параметру и т.д.Теперь нашу программу можно записать так:program MAXD(input, output);var x,y,u,vs real; s: real;procedure MAX2B(rl,r2:real);begin if rl>r2 then s:=rl else s:=r2 end;begin read(x,y);MAX2B <X+y,X*y);u : ;MAX2B <0.5, u); v:=s;wri teln(' .u=',u, '_v=' ,v)end.Выполнение оператора процедуры MAX2B (x + у, x * у) равносильновыполнению следующего эквивалентного ему блока:var г 1,r2: real;begin rl:=;;+y;r2:=x*y;begin if rl>r2 then s:=rl else s:~-r2 endendТаким образом, при обращении к процедуре в ней вводятся в употребление свои внутренние переменные, имена которых совпадают с формаль148ными параметрами. Эти переменные существуют только на время выполнения процедуры, после чего они прекращают свое существование.
Привходе в процедуру этим внутренним переменным присваиваются значения,заданные соответствующими фактическими параметрами в операторепроцедуры — эти значения и используются при выполнении процедуры.Аналогично выполняется и оператор процедуры МАХ2В (0.5, и ) .Как видно, теперь в основной программе отпала необходимость вводитьв употребление переменные а и Ь, а перед обращением к процедуре — присваивать этим переменным соответствующие значения. Благодаря этомураздел операторов в основной программе стал еще более к о м п а к т н ы ми наглядным.Рассмотренные здесь формальные параметры процедуры носят название параметры-значения, поскольку каждый такой параметр в теле процедуры представляет некоторое значение, задаваемое при обращении кпроцедуре с помощью соответствующего фактического параметра.
Фактическим параметром в этом случае может быть любое выражение того жетипа, что и тип формального параметра, в частности — константа или переменная соответствующего типа к а к частный случай выражения.Следует подчеркнуть, что в данном случае фактические параметрыиспользуются только при входе в процедуру, с целью передачи задаваемыхими значений тем внутренним переменным процедуры, которые поставлены в соответствие ее формальным параметрам-значениям. После этогофактические параметры недоступны из процедуры, так что она не в состоянии ни использовать фактические параметры каким-либо иным способом, ни изменить значение переменной, являющейся фактическим параметром. Так, если бы рассматриваемая нами процедура была описанаследующим образом:procedure МАХ2С (rl,r2: real ) ;begin if rl>r2 then s:=rl else s:=r2; ri:=0; r2:=0 endто выполнение оператора процедурыMAX2C(0.5, u'было бы равносильно выполнению эквивалентного ему блокаvar r l , r 2 :real;begin г 1:=0.5; r 2 : = u ;begin i f r l > r 2 then s : = r l e l s e s : = r 2 ;rl:«=0;r 2 : = 0 endendКак видно, операторы r l : = 0; r2: = 0 изменяют значения только внутренних для данной процедуры переменных rl и т2, к о т о р ы м первоначальнобыли присвоены значения фактических параметров 0.5 и и, но сами этифактические параметры не изменяются.
А поскольку эти внутренние переменные по окончании выполнения процедуры вообще прекращают своесуществование, то их значения (возможно, измененные по ходу выполнения '.роцедуры) никак не могут быть использованы вне процедуры. Отсюда, в частности, следует, что с помощью параметров-значений нельзя представлять те результаты выполнения процедуры, которые должны использоваться вне тела процедуры, в основной части программы.1498.2.2.
Параметры-переменныеНедостаток процедуры МАХ2В состоит в том, что найденное большееиз двух значений она всегда присваивает одной и той же переменной s.В нашей же задаче в одном случае найденный результат надо присвоитьпеременной и, а в другом случае — переменной v. Поэтому после оператора процедуры в программе приходилось записывать дополнительныйоператор присваивания.Этот недостаток можно устранить, если в процедуре не фиксироватьпеременную, которой присваивается найденное значение, а сделать ее тожепараметром процедуры, обозначив эту переменную, например, идентификатором res, который также будет формальным параметром процедуры.Однако этот формальный параметр существенно отличается от формальных параметров rl и г2: он в теле процедуры должен представлять не значение, являющееся одним из исходных данных этой процедуры, а некоторую переменную, существующую вне тела процедуры.
И чтобы процедурамогла присвоить значение такой переменной, необходимо обеспечить непосредственный доступ к ней из процедуры.Чтобы отличить параметр-переменную от параметра-значения, передним в списке формальных параметров записывается служебное слово var.После формального параметра-переменной по-прежнему должен быть указан ее тип.
В отличие от формального параметра-значения, фактичгским"параметром для которого может быть любое выражение соответствующеготипа, для параметра-переменной фактическим параметром может бытьтолько переменная, но не любое выражение.В этом случае нашу программу можно записать так:program МАХЕ(input, output);var x,y,u,v:real;procedure MAX2D (rl,r2: real; var res: real);begin i-f r 1 >r2 then res:=rl else res:=r2 end;begin read(>:,y);MAX2D (x +y , x *y , u) ;MA X2D(0.5,u , v);writeln('u-',u,' v=',v>end.Теперь раздел о п р а т о р о в основной программы получился предельнокомпактным и наглядным — в нем не осталось никаких вспомогательныхоператоров.Как же теперь будет выполняться оператор процедуры, напримерMAX2D(x + у, х * у.
и)? Фактические параметры-значения используютсятак же, как и раньше. А вот фактический параметр-переменная используется совсем иначе. В данном случае везде в теле процедуры формальныйпараметр-переменная res заменяется на заданный фактический параметр переменную и, в результате чего получаетсям о д и ф и ц и р о в а н н о е тело процедуры, которое затем и выполняется. Таким образом, выполнениеуказанного выше оператора процедуры равносильно выполнению сле150дующего эквивалентного ему блока:var г 1,r2: real;begin rl:=x+y;r2:=x*y;begin i-f rl>r2 then u:=rl else u:=r2 endendИтак, если формальный параметр объявлен параметром-переменной,то процедура получает непосредственный доступ к той переменной, которая задана в качестве соответствующего фактического параметра. В связис этим процедура может непосредственно использовать и изменять значение этой переменной, и тем самым передавать в основную программувырабатываемые ею результаты.
Если говорить более точно, то при обращении к процедуре ей передается ссылка на переменную, заданнуюв качестве фактического параметра — эта ссылка и используется процедурой для доступа к этой переменной.8.2.3. Параметры производных типовДо сих пор мы рассматривали параметры, представляющие или задающиезначения или переменные простых типов.
Однако в паскале имеются и производные типы — значения этих типов в общем случае являются некоторыми структурами данных. Что касается параметров-переменных, то здесьне возникает каких-то трудностей в понимании — все обстоит так же, к а ки в случае скалярных типов. Что же касается параметров значений, то этотслучай заслуживает более внимательного рассмотрения.Как мы уже говорили, фактическим параметром-значением может бытьлюбое выражение соответствующего типа. Однако в паскале для значенийпроизводных типов не определены какие-либо операции, дающие результат такого же типа, также нет и констант производных типов (за исключением строковых констант). Так что в любом случае фактическим параметром может быть только переменная такого типа.
Указанная ситуацияимеет место, в частности, для массивов.Пусть, например, в программе имеются следующие описания:const N=20;type Вект=аггау C1..N] o-f real;var u,v: real; i: integer;X,Y: Вект;Пусть в программе — после определения значений переменных Xи Y регулярного типа — требуется найти u = шах{Х,}, v =max{Y I -}(г = 1, 2, ..., N ) . Поскольку здесь дважды должен использоваться частичный алгоритм нахождения наибольшей компоненты вектора, то этот алгоритм удобно оформить в виде процедуры, описание которой может иметьвид:procedure MAXAR(А: Вект; var s: real);begin s:=AClD;for i:=1 to N doi-f ACi D >s then s:=ACi]end;151При наличии такого описания процедуры в разделе процедур и функцийпрограммы, для получения значения и по указанному выше правилу в основной программе достаточно записать оператор процедурыMAXAR(X,и);Как будет выполняться такой оператор процедуры? Поскольку второйформальный параметр s процедуры объявлен параметром-переменной,то он в теле процедуры будет заменен на фактический параметр и.