Р.У. Себеста - Основные копцепции языков программирования (2001) (1160794), страница 91
Текст из файла (страница 91)
— заголовок подпрограммы на языке гОКТКАЫ с именем АРРЕК. В языке Айа за- -: поаок подпрограммы йРРЕК мог бы выглядеть так: ргоовс(иге йРРЕК(параметры) = заголовке подпрограммы на языке С не предусмотрено никакого специального слова. З языке С есть только один вид подпрограмм — функции — и заголовок функции распо:-зется по контексту, а не с помощью специального словв Например. прнвеленная ниже :=ока может служить заголовком функции с именем ас)с(ег, где спецификатор чо1б : .качает, что эта функция не возвращает никакого значения: ягосс( ас(с)ег(параметры) Профиль параметров (рагаше(ег ргой1е) подпрограммы — это количество, порядок . типы формальных параметров. Протокол подпрограммы — это профиль подпрограм.
м плюс, если это функция, тип возвращаемого ею значения. В языках, в которых под-рограммы имеют типы, эти типы определяются протоколом подпрограммы, Подпрограммы могут содержать как обьявления, так н определения переменных. '! ченно так обстоит дело в языке С, в котором объявления могут использоваться лля пре- 8.2. Основм подпрограмм доставления информации о типе, но не лля определения самой переменной, Объявления и определения необходимы, если на переменную нужно сослаться до того, как компилятор > видит ее определение. Объявления подпрограмм предоставляют информацию о ее интерфейсе, который состоит из типов параметров, но не содержит тел подпрограмм. Это необходимо, если компилятор должен оттранслировать вызов подпрограммы перед тем, как он увидит определение самой подпрограммы. В обоих случаях объявления необходимы для статической проверки типов.
Объявления подпрограмм широко распространены в языке С, в котором они называются прототипами. Они также используются в языках Аоа и Рааса!, в которых иногда называются упреждаюшими или внешними объявлениями. Язык Зака не позволяет объявлять свои методы, поскольку в областях их видимости неявно допускаются упреждающие ссылки на них. 8.2.3. Параметры Обычно подпрограммы описывают вычисления. Сушествует два способа доступа к данным, подлежашим обработке: прямой доступ к глобальной переменной (объявленной где-то в другом месте. но видимой в подпрограмме) и передача параметров. Данные, передаваемые через параметры.
доступны по имени, являющемуся локальным по отношению к подпрограмме. Передача параметров представляет собой более гибкий способ, чем прямой доступ к глобальным переменным. По существу, подпрограмма, получающая через параметры доступ к данным, подлежащим обработке, является параметризованным вычислением. Она может выполнить свои вычисления на основании любых данных, получаемых через параметры (при условии, что типы параметров совпадают с ожидаемыми в подпрограмме). Если доступ к данным осуществляется через глобальные переменные, существует один способ обработать другие данные — присвоить новые значения этим глобальным переменным между вызовами подпрограмм.
Широкий доступ к глобальным переменным может снизить надежность программы. Переменные, являюшиеся видимыми в подпрограмме, где необходим доступ к ним, часто также видимы и в других подпрограммах, где они совсем не нужны. Эта проблема обсуждалась в главе 4 и рассматривается в разделе 8.11. В некоторых ситуациях удобно передавать в подпрограммы в качестве параметров не данные, а вычисления. В этих случаях имя подпрограммы. реализуюшей такое вычисление, можно использовать как параметр. Этот вид параметров обсуждается в разделе 8.6.
Передача данных в виде параметров обе>ждается в разделе 8.5. Параметры, приведенные в заголовке подпрограммы, называются формальными параметрами (Гоппа! рагаглегегз), Иногла их считают фиктивными перелгенными, поскольку они не являются переменными в обычнол~ смысле этого слова: в некоторых случаях они связываются со значениями, храняшнмися в памяти, только после вызова подпрограммы, и такое связывание часто осуществляется с помощью других переменных программы. Операторы вызова подпрограмм лолжны содержать имя подпрограммы и список параметров, которые подлежат связыванию с формальными параметрами подпрограммы.
Эти параметры называются фактическими (асгоа! рагашегегз), Они должны отличаться от формальных параметров, поскольку на вид формальных и фактических параметров накладываются разные ограничения, и, конечно, они используются совершенно по-разному. Практически во всех языках программирования соответствие между фактическими и формальными параметрами — или связывание фактических параметров с формальными — осушествляется на основе их расположения: первый фактический параметр соот- 34В Глава 8. Подпрограммы з:-ствует первому формальному параметру и так далее. Такие параметры называются гознционными (ромбопа! рагаше(егз). Для относительно коротких списков параметров --. т способ вполне приемлем.
Когда списки параметров достигают большой длины, программист легко может оши. - ся и расположить параметры в неправильном порядке. Одно из решений этой про-емы — предоставить возможность использования ключевых параметров Всеузчогд -:- глегегз). в которых имя формального параметра, с которым должен быть связан фак-еский параметр, указывается вместе с ним. Преимушество ключевых параметров за..-. чается в том, что они могут появляться в списке фактических параметров в произ-ьном порядке. В языке Ада процедуры можно вызвать именно этим способом, как -:.-азано ниже: '"ИЕВ (ЬЕНСТН => МУ ЬЕНСТН, ЬТЯТ => МУ АВРАУ, ЯОИ => МУ ЯОМ); '.
зесь определение процедуры ЯСИЕВ содержит формальные параметры ЬЕНСТН, ЬТЯТ Главный недостаток ключевых параметров состоит в том, что пользователь подпро--. зччы должен знать имена формальных параметров. Кроме ключевых параметров, языки Ада и РОКТКАИ 90 позволяют использовать н -: знционные параметры. Эти два вида параметров можно смешивать в одном вызове. °:- показано ниже: '".СЕВ(ИУ ЬЕНСТН, ЯСМ => МУ ЯОМ, Ь1ЯТ => МУ-АВВАУ) = = 1нственное ограничение, наложенное на такой способ указания фактических парамет- з. заключается в том, что после первого появления в списке ключевого параметра все ;сальные параметры должны быть ключевыми. Это необходимо потому, что после по-з агния в списке ключевого параметра позиции следующих параметров уже нельзя точопределить.
В языках С++, РОКТКАИ 90 и Ада формальные параметры могут иметь значения по ".лчанию. Значение по умолчанию используется, когда формальному параметру. ука-ному в заголовке подпрограммы, не передается никакого фактического параметра. =::смотрим следующий заголовок функции на языке Ада: Еппсвйоп СОМРСТЕ РАУ(1НСОИЕ : РЬОАТг ЕХЕИРТ10НЯ : 1НТЕСЕВ := 1; ТАХ ВАТЕ : РЬОАТ) кекикп РЬОАТг .зраметр ЕХЕМРТ10НЯ при вызове функции СОМРОТЕ РАУ можно пропустить. при -.ом вместо него используется значение 1. В вызовах функций на языке Аба вместо провЂ,щенного параметра запятые не используются, поскольку единственным предназначе-ием такой запятой является указание на позицию следующего параметра, который в =энном случае не нужен, потому что все фактические параметры после пропущенного =.
лжны быть ключевыми. Рассмотрим следующий вызов функции: РАУ := СОМРОТЕ РАУ(20000.0, ТАХ ВАТЕ => 0.15)г 8.2. Основы подпрограмм В языке С++, в котором нет ключевых параметров, правила использования параметров по умолчанию совершенно другие. Параметры по умолчанию должны указываться в конце списка, поскольку соответствие между параметрами в языке С++ устанавливается по их позиции в списке. Если параметр по умолчанию в вызове пропущен, все остальные формальные параметры должны иметь значения по умолчанию. Заголовок функции сО(чрцте РАУ на языке С++ можно записать следующим образом: х1оаа соврпсе рау(х1оаа 1псове, к1оаа Сах гасе, дав ехеврс1опв = 1) Отметим, что параметры в этой функции указаны в другом порядке таким образом, что параметр по умолчанию указан последним.
Пример вызова функции соврпте рау на языке С++ приведен ниже: рау = соврисе рау(20000.0, 0.15); В большинстве языков программирования, не имеющих значений по умолчанию для формальных параметров, количество фактических параметров в вызове должно совпадать с количеством формальных параметров в определении заголовка подпрограммы. Олнако в языках С и С++ это не требуется. Если количество фактических параметров в вызове функции меньше, чем количество ее формальных параметров, ответственность за соответствие между параметрами, всегда являющееся позиционным, и разумное выполнение полпрограммы возлагается на программиста.
Несмотря на то что этот способ, позволяющий испольювать переменное количество параметров, очевидно предрасположен к ошибкам, он иногда бывает удобен. Например, функция ргьпг й в языке С может напечатать любое количество элементов (ланных и/или литеральных строк). Подпрограммы на языке Ада должны иметь фиксированное количество параметров, так что встроенная процедура вывода на языке Ада печатает только одно значение. Такие подпрограммы вывода данных гораздо трулнее использовать.
,8.2.4. Процвдуры и функции Подпрограммы разделяются на две различные категории: процедуры и функции, каждая из этих разновидностей может рассматриваться как способ расширения языка. Процедуры представляют собой наборы операторов, определяющих параметризованные вычисления. Эти вычисления активизируются отдельными операторами вызова. В действительности процедуры определяют новые операторы.