Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 80
Текст из файла (страница 80)
Б.12. Общий сегмент кода и различные записи активации длп подпрограммы Общие подпрограммы В спецификации подпрограммы обычно указывак>гся количество, порядок следо- вания и тиц данных ее формальных параметров. 06>цая лодлрогрпмма — это под- программа, имеющая одно имя, но несколько различных определений, характе- ризующихся различными сигнатурами. Говорят, что имя общей подпрограммы перегружено. Общая кош>епция общих операций и перегруженных имен обсужда- лась в главе 5 на примере элементарных операций.
Подпрограммы с этой точки зрения также могут быть обп>ими. Например, прп создании большой программы распределения студентов по различным курсам лекций в университете н числе >ьругих подпрограмм могут пгпребоваться слсдукнцис: одна, которая включает ка- кую-либо группу н таблицу со списком групп, и лй>у>ая, которая вносит фамилию студента в список группы.
Обе зти подпрограммы могут Г>ыгь названы Еп1ег: ргосеоыге Епсег(51ыпеп1: тп >п1едег, 5ес1; зп оы1 5ес1>оп> зз Ьед1п - здесь лоиеыаются операторы включения студентов в список группы епб. ргосеоыге Епсег<5 Зп 5есг>оп ТаЬ. тп оы1 С>азв» з1> зз Ьедзп - здесь поиецаются операторы вклонения групп в список епб. Имя Еп1ег является перегруженным и становится именем общей подпрограм- мы Еп1ег.
Когда происходит вызов процедуры Еп1ег 1Ел1ег(А. ВП, транслятор со- поставляет типы фактических параметров А и В с спнщми формальных параметров в объявлениях обеих >гроцедур Еп1ег Если перел>синая А окажется типа >п1едег, зто будет означать, что следует вызывать первую из приведенных в листинге про- цедур. Если же тип переменной А является 5ЕС1>оп, то — вторую процедуру.
По- 284 Глава б Инкапсуляция скольку это разрешение имен осуществляется еще во время трансляции, то в таких языках, как Ада, перегрузка имени ие оказывает влияния иа оргаиизацпю этапа выполиепия программ, написали)>)х па этом языке. Если вопрос с перегрузкой решен, то далее траисляция вызова одной из родственных подпрограмм происходит так же, как и для любой другой подпрограммы. В РОЙТМАН 90 перегруженные процедуры определяются в спсциальиом бло- ке !ИТЕРА! ЯСЕ, который пазывается интерфейс иым блоком.
Наш )!ример с двумя процедурами вклк)чспия в список студента или группы будет выглядеть следующим образом: Листинг б.2. Интерфейсный блок в ЕОГТТГ)АЬ) 90 !ИТЕВГЯСГ ЕИТЕВ 50ВВООТ!ИЕ ГИТЕВ 5ТООЕИТ!50)ОГИТ 5ЕСТ) )ИГЕВЕВ 5ТСОЕИТ 5ЕСТ10И . 5ЕСТ ЕИО 50ВВООТ!ИЕ ЕИТЕЙ 5ТООЕИТ 50ВВООТ1ИЕ ЕИТЕВ 5ЕСТ10Иг15. ТЯВ) 5ЕСНОИ, 5 СЕЯ55015Т.. ТЯВ ЕИО 5))ВВООТ!ИТ. ЕИТГВ 5ЕСТ10И ЕИО 1ИТЕВГЯСЕ ЕИТЕВ В этом примере подпрограмма ЕИТЕВ определена таким образолт, что может получать в качестве фактического параметра либо объект типа ! лгеВег, либо объект типа эесг)ол. Следующим шагом в развитии этой копцепции является включение иепосредственио сал)о! о типа в параметры подпрограммы, как это сделано в языке МБ с помощью механизма полиморфпых типов. Возможпость определять общие под!!рограммы пе требует каких-либо зиачительных изменений языка или его возможпои реализации, по оказывает большое влияпие па использование языка.
Поэтому перегрузка имени подпрограммы, которая в языке А<! а является просто дополнительной возможностью, в МБ уже стаиовится одной из существенных особенностей программирования па этом языке. Более подробно это обсуждается в главе 7. 6.3.3. Определения подпрограмм как объектов данных В болыпиистве компилируемых языков, таких как С, С.Г.Г и0ача, определение подпрограммы отделено от ее выполпеиия. Сначала исходная программа обрабатывается компилятором и преобразуется в исполняемый код. Во время вьшолиеиия статическая часть опрсделеиия подпрограммы педоступпа и невидима.
Но в таких языках, как 1!БР, Рег! и Рго!ой (которые обычно реализуются при помощи программиых иптерцрстаторов), как правило, между этими двумя фазами различие отсутствует. Возможпости этих языков позволяют обращаться с определениями подпрограмм, как с некими объектами даипых времени вьшолнеиия.
Траисляция — это операция, которая получает определение подпрограммы в виде строки символов и создает обьект даипых времени выполпепия, представляющий это определение. Выполнение — это операция, которая получает определеиие подпрограммы в форме объекта дапцых времеви выполиеиия, создает иа его основе 6.4. Определения типов 285 активацию и вьнюлняет ее. Операция выполнения запускается цри помощи элементарной команды вызова подпрограмм, но операция трансляции часто рассматривается как отдельная метаоперация, которая выполняется для всех подпрограмм ло начала выполнения основной программы.
В языках 1)ВР и Рго!ой трансляция, однако, является операцией, которую можно инициализировать во время выцолнения основной программы и которая в качестве аргумента получает символьную строку (оцределение цодцрограммы), а в качестве результата выдает исцолняемый код тела нодцрограммы, В этих языках имеется специальная операция Ое~1ве, аргументами которой являются тело и спецификация цодцрограммы, а результатом — готовое к использованию определение подпрограммы (нацример, операции ое(1пе в ПВР, сопьц)г. в Рго!ой). Таким образом, в обоих этих языках можно запускать программу, не имея в наличии конкретной подпрограммы.
Во время выполнения программы тело цодпрограммы может быть считано из какого-либо внешнего источника или создано как объект данных символьного типа и затем оттранслировано в исполняемую форму. Затем применяется оцерация се Г1 пе для определения имени подпрограммы и цараметров, используемых в теле подпрограммы. В результате получается иоллос определение подпрограммы. Впоследствии зта подпрограмма может вызываться цо мере надобности Определение подпрограммы позже может быть изменено, Таким образом, в таких языках онрелелення подпрограмм становятся полноценными объектами данных.
6.4. Определения типов При определении совершенно нового абстрактного тица данных необходим некоторый механизм для оцределения класса объектов данных. В таких языках, как С, Разса! и Аг)а, этот механизм называется определением типе (заметим, что это апрелеление типа все же пе определяет полностью абстрактный тин данных, поскольку в него не вхолит определение операций, црименимых к вновь созлаццому типу). В определении тица задается имя этого типа и объявления, которые описывая>т структуру класса объектов данных.
Имя тина становится затем именем этого класса объектов данных. Когда нам в программе цотребуется использовать объект данных этого типа, нужно булет только указать имя типа, а цовторяты олное описание структуры этого объекта не понадобится. Если в некоторой программе на языке Рааса! исцользуются три записи А, В и С, имеющие одну структуру (нацример, эти записи могут нрелставлять рациональные числа), то программа может содержать слелующес определение типа: суре асыовщ - гесогв алегагог 1пгедег: 0еяоеюасог 1всеяег епе' которое используется в объявлении уаг А. В. С йм1ояю; Таким образом, определение структуры об ьекта данных типа йа11ова) залается один раз, а не повторяется для каждой из трех записей А, В и С.
286 Глава б. Инкапсуляция В языке С похожая ситуация, цо ~ ~соколики более сложщэя ио сравнен и>о с рассмотрслшым примером из Рааса). Новыс типы данных могут оирслсляп гя только ирн иомсици конструкции з Мюг. Следовательно, тии Каст опа1 может Г>сить задан в С слслуинцим образом: лсгис1 Каюопа11уре (тпс пииегасог тп1 Оепсвтпасоп ) Использование нового тина в языке С тем не менее требует указания в объявлении конструкции згтис1.
В т~рогралсмс это булет выглядсть слслующилс образом: ятгис1 Ка11апа1Туре А, З. С: На самом леле то, что получилось, не вполне отвечает пршннтнам абстракции данных. Дело в том, что цам хотелось бы внелр>п с новьн) тин данных в язык таким обраэолс, чтобы он синтаксически и семы>тически ничем не отличался от элементарп ых типов лап ных, встроен и ы х в азы к. Слслощпсл ьно, пал ич ие ключевого слова эсгис1 нсжелателы ю. Причшю жс в том, что язык С достаточно старый — он начал развиваться еще в начале 70-х гг., когда понятия инкапсуляции и сокрьпия информации ссцс пс были полностью сформированы. К счастью, в С предусмотрена конструкция 1урес)еу, реализующая выход из этого положения: 1урес>еу определение типа иия Фактически здесь происходит замена соответствукццсго определения типа (определение типа) на новос имя типа (иня), почти как в макроиолсташ>вке.
Таким образом, на языке С опрслеленне типа Кагтопа1 можно записать следующим образом: суре>>ет я1гис1 Ка1>опа1Туре 1>п1 пииегаспг; тпс Сепсюпа1ог; ) Каттопа1: Затем можно использовать это определение в объявлении: Кастопа1 Я, В. С, Таким образом, мы получаем такой жс синтаксис лля определения объектов нового тина, как и в Рааса). Каттопа1 здесь обозначает новый тип данных,определенный как зггис1 Ка1>опа1Туре. Важно помнить, что в языке С новый тип данных генерируется цри помощи конструкции зтгис1, в то время как конструкция 1урес)ей несмотря на снос название, играет роль макрополстановки цля определения типа.