К. Йенсен, Н. Вирт - Паскаль - Руководство для пользователя (1109480), страница 16
Текст из файла (страница 16)
Параметры-пере- )1 Лроцедерп~ и фепхчии )И менные следует использовать для представления резильтатое процедур, как, например, используются М1п и Мах в процедуре М(пМах. Более того, если Х1, ..., Хп — фактические переменные, соответствующие формальным параметрам-переменным У1, ..., Уп, то все Х1, ..., Хп должны быть разными переменными. Вычисление всех адресов производится в момент активации процедуры. Следовательно, если переменная есть компонента массива, то ее индексное выражение вычисляется при обращении к процедуре. Заметим, что ни компонента упакованной структуры, ни поле признака из записи с вариантами не должны фигурировать в качестве фактических параметров-переменных, чтобы не возникали зависящие от реализации проблемы вычисления адресов.
Если в начале раздела параметров никакого служебного слова нет, то речь идет о параметрах-значениях. В этом случае фактические параметры должны быть выражениями (в наипростейшем случае это переменная). Соответствующий формальный параметр представляется в вызываемой процедуре некоторой локальной переменной. В качестве начального значения этой переменной берется текущее значение соответствующего фактического параметра (т.
е. значение выражения в момент активации). После этого процедура может изменять значение такой переменной, например, с помощью присваивания. На значение фактического параметра такое присваивание не окажет никакого влияния. Следовательно, параметр-значение никак нельзя использовать в качестве результата вычислений. Обратите внимание, что параметры-файлы или составные переменные с компонентами-файлами нельзя специфицировать как параметры-значения, поскольку они подразумевают присваивания. Разница между параметрами-переменными и параметрами- значениями хорошо видна на примере программы 11.3.
Пгпвгае Рагаеееега(О»Ь»»Ь); ( Программа 11.3 — Пример параметров-аначений и параметров-переменных.) паг 4, В: 1»еепег; »го»ее»ге АП»1(Х: 1п(евег; паг у; 1пСевег); Ьев(п Х:= Х + 1; т; У + 1; Нгые1п(О»ер»Ь,Х,Х) епп 1 Ап»1 ); Ьевто А:= О; В:= О; А»О)(А,В); 120 Руководство для пользователя Уг11е1п(Оптрие,й,в) епй 1 Рагзаеаегз ). Дает в качестве резупьтатов: 1 1 0 1 В приведенной ниже таблице. суммируются сведения о соответствии между списком фактических и формальных параметров Формальный параметр Фактический параметр выражение переменная имя процедуры имя функции имя переменной имя переменной загоповок процедуры заголовок функции параметр-значение параметр-переменная процедуральный ппро.петр' функциональный параметр В процедуре'М1пМах из программы 11.2 ни одно из значений в массиве 1 не изменяется, т.
е. 1 — не результат. Следовательно, 1 можно было бы определить как параметр-значение, не влияя при этом на конечный результат. Однако чтобы понять, почему это не делается, полезно разобраться в реализации. При любой активации процедуры для каждого параметра- значения выделяется новое место в памяти. Текущее значение фактического параметра копируется туда, а при выходе из процедуры эта память просто освобождается. Если параметр не используется для передачи результатов процедуры, то предпочтительнее пользоваться параметром-значением. Обращение к нему идет быстрее, и, кроме того, есть защита от ошибочного изменения данных. Однако в случае параметра сложного типа 1например, массива) нужно соблюдать осторожность, поскольку операция копирования относительно дорога и для копии может потребоваться слишком много места в памяти.
Так как мы обращаемся к каждому элементу массива 1. лишь по одному разу, то лучше описать соответствующий параметр как параметр- переменную. Размер массива изменяется путем простого переопределения Мах%хе. Если программу необходимо применять к массивам вещественных чисел, то нужно изменить только определение типа и переменных; на операторах же никак не сказывается, что данные целые. ДС Процедуры и функции 121 11.1.2. Совмептаемые массивы-параметры Для передачи в процедуру или функцию массивов переменного размера можно воспользоваться и другим способом: использовать в качестве параметров-значений или параметров-переменных совмешаемые массивы-параметры. Однако будьте осторожны, в стандартном Паскале такая возможность лишь допускается и некоторые реализации ее не предусматривают. Р и с.
! !ДС Синтаксическая диаграмма для Схемы совмегцаемого массива Имя типа Им» и Р и с. ! !.8. Синтаксическая диаграмма для Спецификации типа индекса Совмешаемые массивы задают реальные границы по каждой размерности через имена границ, представляюшие собой в некотором роде информацию, которую можно лишь читать. Тип индекса фактического массива-параметра должен быть совместим с типом из спецификации типа индекса для совмешаемого массива. Минимальное и максимальное значения этого типа индекса должны лежать внутри замкнутого интервала типа индекса из спецификации. Тип компонент должен быть одинаковым, и если тип компонент совмеШаемого массива-параметра в свою очередь совмещаемый Массив-параметр, то тип компонент фактического массива-параметра должен быть совместим с иим.
Любой совмешаемый массив-параметр может быть упакован лишь по последней размерности. Фактическими параметрами для совмешаемых массивов-параметров-значений могут быть переменные или ст оки. 122 Руководство для яольвовителя Программа Ма(пхМц! из гл. б при использовании совмещаемых массивов-параметров может при переписывании превратиться в программу 11.4. В программе же 11.7 демонстрируется передача через формальный совмещаемый массив-параметр строк различного размера.
! 1.1.3. Рекурсивные процедуры Использование имени процедуры в тексте самой процедуры предполагает рекурсивное выполнение атой процедуры. Задачи, естественным образом формулируемые как рекурсивные, часто приводят к рекурсивным решениям. В качестве примера рассмотрим программу 11.5. Проблема заключается в том, что нужно построить программу, преобразующую выражения в постфиксную нотацию («польскую запись»). Это делается с помощью преобразующих процедур для каждой из синтаксических конструкций (выражения, слагаемого, множителя).
Поскольку эти синтаксические конструкции определяются рекурсивно, то соответствующие процедуры могут рекурсивно активировать сами себя. В качестве исходных данных программа должна воспринимать такие, например. символьные выражения: (а«Ь)ь(с-6) зьь»с-6 ( а " Ь)" с-6 а+Ь'(с-6) а'а'а»а Ь+с'(6+с'а'з)'Ь+а Выражения строятся в соответствии со следующими формулами РВНфь Выражение = Слагаемое 1(«+М « — ») Слагаемое). Слигаемое = — Множитель 1««» Мни»титель). Множитель = Имя 1«(«Выражение»)».
Имя Буква. реаягае Наст(хйи12(1прас, Оц(рсс); ( Программа 11.4 — Вариант Программы 6.3, процедура использует совмещеемые массивы-параметры.) еп6 еп6 [ Ио11!р1у ); ЬеВ!и Кеа6Маог!х(А); Нг!ЬеМаогзх(А); Кеа6Маог!х(В); Нг!ЬеМаСг!х(В); Ио1Ь!р1у(А,В.С); НгРЬеМайг!х(С) еп6 Дает в качестве результатов: 3 2 1 — 3 1О -4 4 -2 1 6 1 -9 наг Зоа: 1псеВег; 1, 3, И: Роз!Ь!не; ЬеКхп !! (!оАКои <> 1) ог (!оАСо! <> 1) ог (!оВКои 1) ог (!оВСо! = !) ог !ЬоСКои <> 1) ог (!оССо! <> 1)- ог (Н!АКои <> Н!СКоы) ог (Н!ЯСо1 <> Н!ВКои) ог (Н!ВСо1 <> Н!ССо1) ЬЬеп [еггог) е1зе !ог 1:= 1 Ьо Н!СКои оо ЬеК!и !Ог 3 := 1 Ьо Н!СС01 60 ЬеВ!и Зов := 0; !ог К;= .1 Ьо Н!АСо! 6а Зоа = Зоа + А[1,К[ " В[М,3[; С[1,3) := Зоа еп6; ргоогав РоеСГ!х(1приС,ОисриС); ! ( Программа 11.5 — Преобразование инфиксных выражений в постфиксную нотацию! !аЬе1 13 (реакция на конец файла). наг СЬ: СЬаг; ргосебиге Гтпб; Ьеп!и !! Еа!(1приС) Спеп ОоСо 13; гереаС Кеаб(1приС, СЬ); ипС!1 (СЬ <> ' ') ог Ео1(1приС) епб ! Г!пб ); ргосебиге Ехргеее!ап; наг Ор: СЬаг; ргосебиге Тегв; ргосебиге Гассет; Ьеа!и !! СЬ = '(' СЬеп е Ьеп!и Г!пб; Ехргеае!оп; ( СЬ = ')' ) епб е1ее Иг!Се(риСриС, СЬ); Г!пб епб ( Гассет ); Ьеа!и ( Тегв ) Гассог; нЬ!1е СЬ = '*' бо Ьеб!п Г!пб; Гассог; Иг!Се(бисрис, " ') епб епб ( Тегв ); Ьеб!и ( Ехргезмоп ) Тегв; нп!1е (СЬ = '+') ог (СЬ = '-') бо Ьеб!и Ор := СЬ Г!пб; Тегв; Иг!Се(ОисриС, Ор) епб епб ( Ехргеае!оп ); 126 Руководство длл полвзовотвлл Ьеп)п ( Рпзсргх ) Е)пд; гереее Ехргезз)еп; Нггсе1п(йперсс) рпс)! СЬ = '.'; 13: еп6 ( Репер)х ! .
Дает в качестве результатов: е аЬ+сд-в аЬс'+деЬ+с'деЬсд-'+ аа'е'а" Ьсеса'ее+'Ь'+л+ Двоичное дерево — это такая структура данных, которая естественно определяется с помогцью рекурсии и обрабатывается рекурсивными алгоритмами. Она состоит из конечного множества вершин. которое либо пусто, либо содержит вершину (корневую) с двумя присоединенными к ней двоичными деревьями, называемыми левым и правым поддеревьями (6]. Рекурсивные процедуры для формирования и обхода двоичных деревьев естественным образом отражают рекурсивную природу такого определения. Программа 11.6 строит двоичное дерево и обходит его в прямом, естественном и обратных порядках.
Само дерево задается в прямом порядке, т. е. путем перечисления вершин (в данном случае обозначаемых ошюй буквой), начиная с корня, затем сначала левого поддерева, а потом правого. Например, дерево, приведенное на рис. 1!.9, вводится как последовательность а)ус..с(е. (п...(1!..1)с! ..гп..п.. причем точками обозначены пустые поддеревья. 11.1хн Процедурельные параметры Лля иллюстрации возможности передачи процедуры в качестве параметра мы перепишем программу 11.6. В списке формальных параметров процедуры или функции процедуральные параметры выглядят как заголовки процедур.
В соответствуюг)тем же месте списка фактических параметров должно обязательно указываться Проигаери и фрчиини гат имя процедуры. Кроме того, в программе 11.7 показано, как фактическое значение строки передается на место совмешаемого массива-параметра. Р и с. 11тн Строение двоичного дерева ргоагав Тгаеегва111прие,беернй); Программа 11.6 — Обход двоичного дерева ) еуре Рйг = 1йоое; 126 Руководство для пользователя йоде = гесог6 1п!о: СЬаг; ЕЕ!пП, К!!пП: РСг епд; чаг КооС: РСг; СП. Спаг; ргасеаиге РгеОгаег(Р. РСг), Ьеесп с! Р с> п!1 Спеп Ьее(п Ыг!Се(ОиериС, Р1 .
1п(о); РгеОгрег(РТ . 11!пМ); РгеОгдег(РТ . КС !па) епа епа ( РгеОгйег ); ргосеаиге 1пОгаег(Р: РСг); Ьеетп !Т Р «ь и!1 Спеп ЬеК!и ТпОгбег(РТ.СС!па); Ыг!Се(ОиериС, РТ. Тп!а); 1пОгаег(РТ.К(спП) епа епа ( 1пОгаег ); ргосебиге РааСОгйег(Р: РСг); ЬеК!и с! Р к> пч! СЬеп ЬеК!и РааСОгаег(РТ.СС!пП);РоаСОгаег(РТ.КС!пп);Ыг!Се(ОиериС,Р(.1п(а) епо епО ( РааСОгаег ); ргасеаиге Еп(ег(чаг Р: РСг); Ьеесп КеаО(1приС, СП); Ыгсее(Оиериь, СП); т! СП <> '.' СПеп Ьее!п Иеи(Р); Р1.1п(о:= СЬ; Епеег(РТ.СС!па); Епеег(РТ.КЕ!пп) епа е!ае Р:= п!1 епд ( ЕпСег ); Под: ° ', Тгзчегса! Епеег(роое); Ыгсее1п(ОиериС); РгеОгаег(КоаС); Ыг!Се1п(ОиериС); 1пОгрег(раоС); Ыгсае1п(0иариС); Роа(Огбег(КаоС); Ыг!Се1п(ОиСрие) епа ( Тгачегаа! ) 11.