Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 115
Текст из файла (страница 115)
Совместное использование данных через передачу параметров особенно полезно, когда подпрограмма при каждом вызове должна обрабатывать разные передаваемые ей данные. Например, если подпрограмма Р используется таким образом, что при каждом очередном своем вызове она должна заносить новые данные в некоторую таблицу, совместно используемую несколькими подпрограммами, то, как правило, эта таблица реализуется при помощи ссылок на нелокальную среду, а заносимые в таблицу данные передаются как явные параметры при каждом вызове Р. В языках программирования используется четыре подхода к нелокальным средам: 1) явные общие среды ссылок; 2) неявные нелокальные среды, основанные на динамической области видимости; 3) на статической области видимости; г() на наследовании. В следующих подразделах мы обсудим передачу параметров и первые три из перечисленных подходов к нелокальным средам.
Наследование мы уже рассматривали в главе 7. 9.3.1. Фактические и формальные параметры Сначала мы рассмотрим совместное использование данных через параметры, а затем обсудим использование параметров для передачи подпрограмм и меток операторов. В предыдущих главах термин аргумент использовался для обозначения объекта данных (или некоторой величины), который пересылался подпрограмме или элементарной операции как один из ее операндов (то есть как фрагмент данныхх, испо чьзуемый при вычислении). Термин результат обозначал фрагмент данных (объект данных или величину), который возвращался после выполнения подпрограммы или операции. Аргументы подпрограммы могут быть переданы ей или через параметры, или через нелокальные ссылки (и, реже, через внешние файлы).
Аналогично, результаты работы подпрограммы могут быть возвращены через параметры, через присваивания значений нелокальным переменным (или файлам) или через явные значения функций. Таким образом, термины аргумент и результат относятся к данным, которые передаются подпрограмме и возвращаются из 9.3. Передача параметров 417 Фактический параметр в Р Вызов процедуры в Р 1, В: локальные переменные в Р 2), тгце: константы 50В(1,В) 50В(2у.тще) 50В(Р1.Р2) 50В(61.62) 506(А[1),В.ВИ 50В(!чЗ,ГМ(6)) Р1, Р2; формальные параметры в Р 61, 62: глобальные или нелокальные переменные в Р Компоненты массивов и записей Результаты вычисления элементарных олвраций или определенных программистом функций Синтаксис вызова процедуры в языке С является типичным для многих языков.
Вызов подпрограммы, как сказано в разделе 8.2, запись!вается в префиксной форме, при этом сначала записывается нмя подпрограммы, за которым в круглых скобках следует список выражений фактических параметров (хотя существуют и другие формы записи, например инфиксная запись в ЛР[., кембриджская польская запись в ь[ЯР).
Для простоты мы принимаем характерное для языка С прс- нее посредством использования различных языковых механизмов. Если мы сконцентрируем внимание на параметрах и передаче параметров, то центральными для нас станут термины фактический пира мегпр и формальный параметр. Формальный параметр — это разновидность локального объекта данных в подпрограмме. В определении подпрограммы обычно перечисляются имена и объявления для формальных параметров как часть ее спецификации (заголовка). Имя формального параметра представляет собой простой идентификатор, а в его объявлении обычно задают тип и другие атрибуты, как и в случае объявлений обычных локальных переменных.
Например, в заголовке процедуры на языке С 50В(<лг Х: сьаг У), определяются два формальных параметра х и у и объявляется, к какому типу они принадлежат. Тем не менее объявление формального параметра несколько отличается от объявления переменной. В зависимости от выбра) щого механизма передачи формальный параметр может быть псевдонимом фактического параметра или может просто содержать копию значения объекта данных, являющегося фактическим параметром. Фактический паргьнетр — это объект данных, совместно используемый вызывающей и вызываемой подпрограммами.
Фактический параметр может быть локальным объектом данных, принадлежащим вызывающей подпрограмме, он может быть также формальным параметром самой вызывак!щей< подпрограммы, он может быть нелокальным объектом данных, видимым из вызывающей подпрограммы, и, наконец, он может бы ть результатом вычисления функции, вызванной из вызывающей подпрограммы, который сразу же передается вызываемой подпрограмме. В точке вызова подпрограммы фактический параметр представляется выражением, называемым выражением фактического пирах(етра, которое обычно выглядит так же, как и любое другое выражение в языке (например, как выражение, которое может появиться в операторе присваивания).
Например, подпрограмма 506, описанная выше, может быть вызвана с любым из следующих типов выражений фактического параметра. 418 Глава 9. Управление подпрограммами фи ко ное представление и и с пол ьзуем терм и иы список фактических пирачетров и список формильных пврииетров для последовательности фактических и формальных параметров, указанных в вызове подпрограммы и в ее определении соответственно. Если при вызове подпрограммы ей передается параметр в виде выражения фактического параметра любой из перечисленных выше форм, то во время вызова, во перед входом в подпрограмму вычисляется значение этого выражения.
Объекты данных, полученные в результате вычисления выражений фактических параметров, становятся фактическими параметрами, псредаииыми подпрограмме. Позже будет отдельно рассмотрен случай, когда выражения фактических параметров не вычисляются во время вызова подпрограммы, а передаются ей ие вьхчислениыэяи, Установка соответствия Когда подпрограмма вызывается со списком фактических параметров, следует устаповить соответствие между фактическими параметрами и формальными параметрами, перечисленными в определении подпрограммы. Мы последовательно опишем два метода, которхве прпмсвяются для установления этого соответствия, Позициопиое соответствие.
Соответствие между фактическими и формальными параметрами устанавливается ца основе их позиций в списках соответственно фактических и формальных параметров: два параметра, которые занимают одщхаковые позиции в списках, образуют пару. Таким образом, первый фактический и первый формальный параметры составляют пару, затем — вторые параметры из обоих списков и т, д. Соответствие по имени.
В языке Аца и в некоторых других языках при вызове подпрограммы можно явным образом указать, какой формальный параметр лолжец соответствовать данному фактическому параметру. Например, в языке Лоа можно вызвать подпрограмму БиЬ слсдующям образом: Бвь<Х => В Х = 27 Е Здесь при вызове подпрограммы ВвЬ фактический параметр В объединяется в пару с формальным параметром 1, а фактпчсский параметр 27 — с формальным параметром Х. В большинстве языков используется исключительно позиционное соответствие, поэтому в примерах, приведенных в нашей книге, также применяется этот метод. Обычно количество формальных и фактических параметров должно совпадать, чтобы соответствие между ними было взаимно однозначным. Тем це менее в некоторых языках зто требование це выполняется, и в этом случае используются специальные соглашения, иитерпретиручощие отсутствие или избыток фактических параметров.
В вашей книге для простоты мы всюду предполагаем, что количество параметров в обоих списках одинаково. 9.3.2. Методы передачи параметров Когда подпрограмма передает управление другой подпрограмме, требуется связать фактические параметры вызывающей подпрограммы с формальными параметрами вызываемой подпрограммы.
Чаще всего применяются два подхода; либо фактический параметр вычисляется и полученное зиачепие передастся формаль- 9.3. Передача параметров 419 ному параметру, либо фактический объект данных передается формальному параметру Мы описываем это как процесс, имеющий два этапа; 1) описание деталей реализации механизма передачи параметров; 2) описаиис семантики использования параметров. Для передачи фактических параметров в подпрограмму было разработано пссколько методов.
Первые четыре из описываемых далее являются наиболее распростр;шсппымп. Это передача по имепи, передача по ссылке, передача по значению и передача цо значению-рсзультату. Передача по имени. В этой модели передачи параметров вызов подпрограммы рассматривается как подстановка для всего тела подпрограммы. В такой интерпретапии каждый формальный параметр заменяется фалтпчсским значением каждого конкретного фактического параметра. В этом случае каждая ссылка иа формальный параметр в тслс полпрограммы требует вычисления заново значеиия соответствующего фактического параметра, как сели бы были произведены дсйствптсльпыс подстановки.
Эта модель требует, чтобы в точке вызова подпрограммы фактические параметры оставались нс вычисленными до тех пор, пока в подпрограмме действительно ис булст ссылки на них. Параметры передаются не вычисленными, и вызванная подпрограмма определяет сама, когда оии действительно вычисляются, если вычисляются вообще. Напомним из приведенного ранее (глана 8) обсуждения унифицированных правил вычислений, что эта возможность оказалась полезна в трактовке операций типа условной операции 1г-Гпеп-е1зе как обычных операций, Эта методика иногда бывает полезна для элементарных операций, но для подпрограмм, опредсляемых пользоватслслц се полезпость представляется проблематичной изза болыпой стоимости реализации.
Тем цс менее передача параметров по имени играет важную роль в языке ЛЕНОЙ, а также имеет большое теоретическое значение. Но этот метод приводит к значительным затратам при выполнении программ, поэтому сто популярность псвслпка. Осповнос правило передачи по имени может быть сформулировано в тсрлщнах подстановки: до начала выполпеция подпрограммы везде в ес тслс фактический параметр должен бьггь подставлен вместо формального параметра. Хотя это правило кажется иа псрвьш взгляд достаточно простым, рассмотрим проблему, возникающую уже в таком простом вызове подпрограммы са11 5цЬ<Х). Если в подпрограммее 5эЬ формальным параметром является У, то всюду в теле подпрограммы 5вЬ сто следует заменить на Х до начала ее выполнения, Одиако этого еще недостаточно, поскольку, ко~да во время вы полиси пя подпрограмма 5цЬ дойдет ло ссылки па Х, окажется, что ассоциация для Х, па которую мы ссылаемся, является ца самом дслс ассоциацией в вьиывиющеи подпрограмме, а це в подпрограмме 5цЬ (если такая ассоциация там существует).