Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 113
Текст из файла (страница 113)
1. Объявления в заголовке блока определяют среду локальных ссылок для блоки. Любая ссылка на идентификатор в пределах тела блока (пе включая вложенные подблоки) рассматривается как ссылка на локальное объявление идентификатора (если оно присутствует). 2. Если в пределах тела блока имеется ссылка па идентификатор, но локальное объявление идентификатора отсутствует, то эта ссылка рассматривается как ссылка на объявление в первом блоке, который включает в себя данный блок.
Если и в пем искомое объявление идентификатора отсутствует, то поиск продолжается в блоке следующего уровня и т. д. Если же об ьявление не будет найдено и в самом внешнем (верхнем) блоке, то идентификатор либо относится к предопределенным именам данного языка и его объявление берется из среды предопределенных имен, либо (если такого имени нет и среди предопределенных имен) ата ситуация рассматривается как ошибка.
Таким образоьь среда предопределенных имен языка рассматривается как блок, внешний по отношению к самому внешнему блоку программы. 3. Если блок содержит определение другого блока, то все локальные объявления в этом внутреннем блоке или блоках, содержащихся внутри него, полностью скрыты от внешнего блока, в котором, следовательно, не могут появиться ссылки на эти определения. Таким образом, внутренние блоки инкапсулируют свои локальные объявления, делая их невидимыми для внешних блоков.
9.2. Атрибуты управления данными 409 4. Блок может иметь имя (обычио если он представляет собой именованную подпрограмму). Имя блока входит в среду локальных ссылок содержашего блока, ! (апример, если в главной программе па Раяса! содержится определение подпрограммы, которое начинается следующим образом: Ргосевиге Р(А геэш: то имя процедуры Р является локальным именем в главной программе, тогда как имя формального параметра А является частью среды локальных ссылок самой подпрограммы Р. В пределах главной программы можно ссылаться на Р, иоие иаА.
Обратите випмапис па то, что, используя эти правила статической области видимости, можно несколько раз объявлять один и тот же идентификатор в различных блоках, но объявление во внешнем блоке всегда становится скрытым внутри вложенного блока, если в последнем этот идентификатор объявляется заново. Эти правила статической области видимости для блочио-структурированиых программ позволяют связывать каждую ссылку в пределах одного блока с определенным объявлением этого имени в процессе трансляции подпрограммы (если ссылка не является ошибочной). Это пе требует от программиста никаких явных действий, эа исключением создания правильных объявлений в пределах каждого блока и правильного вложения блоков друг в друга. На основе правил статического контроля компилятор языка может провести статическую проверку типов и некоторые другие упрощения структуры выполняемого кода программы.
Все это послужило причиной того, что блочная структура была принята в качестве структуры программы во многих языках программирования. 9.2.4. Локальные данные и среды локальных ссылок Теперь мы начинаем рассмотрение различных структур управления данными, используемых в языках программирования. В этом разделе мы остановимся па средах локальных ссылок, которые образуют простейшую структуру. В следующих разделах рассмотрим иелокальпые среды, параметры и передачу параметров. Локальная среда подпрограммы О состоит из различных идентификаторов, объявленных в заголовке подпрограммы О (но имя подпрограммы не входит в эту среду). Имена переменных, формальных параметров и подпрограмм образуют среду локальных ссылок подпрограммы О. Здесь имеются в виду те полпрограммы, которые локально определены внутри О (то есть подпрограммы, определения которых вложены в О).
Для сред локальных ссылок правила динамической и статической области видимости легко согласовываются между собой, Правило статической области видимости гласит, что ссылка на идентификатор Х в теле подпрограммы О связывается с локальным объявлением Х в заголовке подпрограммы О (в предположении, что такое объявление существует). Правило динамического контроля определяет, что ссылка на Х во время выполнения подпрограммы О для своего разрешения использует ассоциацию идентификатора Х в текущей активации подпрограммы О (заметим, что, вообше говоря, может существовать несколько активаций подпрограммы О, но толь- 410 Глава 9.
Управление подпрограммами ко одна из них может выполняться в настоящий момент). Для реализации правила статической области видимости компилятор просто создает и поддерживает таблицу локальных обьявлений идентификаторов, расположенных в заголовке подпрограммы О, а в процессе компиляции ее тела в первую очередь обращается именно к этой таблице, когда ему требуется найти объявление какого-либо идентификатора. Правило динамической области видимости может быть реализовано двумя способами, каждый из которых задает разную семантику локальных ссылок. Рассмотрим подпрограммы Р, 0 и Р (листинг 9.5). В подпрограмме 0 обьявлена локальная переменная Х.
Подпрограмма Р вызывает подпрограмму О, которая, в свою очередь, вызывает подпрограмму Р. По завершении подпрограммы Р управление передается обратно в О, которая, завершаясь, снова передает управление подпрограмме Р. Проследим за переменной Х во время выполнения атой последовательности обращений к подпрограммам. 1.
Когда выполняется Р, переменная Х це видна из Р, так как опа является локальной переменной подпрограммы О. 2. Когда подпрограмма Р вызывает подпрограмму О, переменная Х становится видимой как имя целочисленного объекта данных с начальным значением 30. При выполнении подпрограммы 0 ее первый оператор ссылается на Х и печатает ее текущее значение 30. 3.
Когда подпрограмма 0 вызывает подпрограмму Р, ассоциация для идентификатора Х становится скрытой, но сохраняется в течение всего времени выполненияя Р. 4. Когда подпрограмма Р возвращает управление О, ассоциация для идентификатора Х снова становится видимой. Х по-прежнему является именем того же самого объекта данных, который по-прежнему имеет значение равное 30. 5. Когда подпрограмма 0 возобновляет свое выполнение, переменная Х увеличивается на 1 и се новое значение 31 выводится на печать. 6.
Когда подпрограмма 0 возвращает управление подпрограмме Р, то ассоциация для Х снова становится скрытой, но для нее можно предусмотреть два различных действия: + Сохринеяие. Ассоциация Х люжст быть сохранена ло следующего вызова подпрограммы 0 точно так же, как зто происходило при вызове подпрограммы Р. В этом случае при следующем вызове 0 идентификатор Х остается связан с тем же объектом данных, значение которого по-прежнему равно 31.
Следовательно, первый оператор подпрограммы 0 выведет на печать значение 31. Если этот цикл повторится и подпрограмма 0 будет вызвана в третий раз, то Х будет иметь значение 32 и т. д. + Уничтожение. Альтернативой сохранению ассоциации является ее удаление (то есть ассоциация, связывающая Х с объектом данных, разрушается, так же как и сам объект данных, а место в памяти освобождается для использования). Когда 0 вызывается во второй раз, создастся новый объект данных, которому присваивается начальное значение 30, и его ассоциация с именем Х создается заново. В этом случае первый оператор подпрограммы 0 при се вызове всегда выводит на печать одно и то жс значение 30.
9.2. Атрибуты управления данными 4! 1 Листинг 9.6. Среда локальных ссылок: сохранение или уничтожение? ргосегтыге В; епг): ргосегтш е 0: чаг Х тптерег - 30: Ьевтп ыгтте (Х). а. Х;= Х» 1: ыгт'те (Хт -начальное значение Х равно 30 -вьвоа на печать значения Х -вызов поапрограмиы 0 -увеличение значения Х на 1 -повторныи вывод Х на печать епл ргоселоге Р. -вызов полпрограииы 0 Реализация При обсуждении реализации орел ссылок удобно представлять локальную среду подпрограммы как птабгтиьу локальной среды, состоящей из пар «идентификаторобъект лщшых» (см. табл. 9.1 для программы, представленной в листинге 9.6). Как уже было сказано, размер выделяемой каждому объекту памяти осуществляется в соответствии с сто типом (см.
главу 6), а местоположение объекта данных в памяти определяется с помощью его бзпачения (см, главу 5). Приведенный способ представления таблицы локальной среды вовсе не означает, что фактические идеитифпкаторы (например, Х) хранятся во время выполнения программы именно таким образом. Обычно это цс так.
Имя используется только для того, чтобы последующие ссылки на эту переменную были способны определить, в каком месте памяти располагается эта переменная во время выполнения программы. С использованием таблиц локальных сред реализация локальных сред на основе подходов с сохранением и уничтожением ассоциаций становится элементарной. Листинг 9.6. Определение подпрограммы зиХХ в языке Рааса( ргоселоге 50ВтХ:тптерег П чаг У. геа!. 2: аггау 11 3] ат геат: ргоселоге 50В2. Ьертп епл (5нЬ2); Ьедгп епл (5но): епг], Сохранение и уничтожение — зто два различных подхода к семантике среды локальных ссылок, н оба они связаны с понятием врелгетти жизни среды.
В языках ']ага, С, Рааса), Аг(а, (.(БР АР1 и Б)ь(ОВО(А используется подход, основанный на уничтожении ассоциации: локальные переменные не сохраняют свои значения в промежутках между последовательными вызовами подпрограммы. В СОВО). и многочисленных версиях ЕОВТВА]ь( используется подход, основанный на сохранении ассоциации; переменцыс сохраняют свои старые значения между вызовами подпрограммы. В Р(«г1 и А(.СО(. предусмотрены оба подхода; для каждой конкретной переменной можно выбрать свой вариант.
412 Глава 9. Управление подпрограммами Таблица 9.1. Таблица локальной среды для подпрограммы ЗоЬ Содержимое /-значения Имя Тип 1птесег геа1 геа1 Определяется параметром Локальная величина Локальный массив дескриптор: 11 ..31 Указатель на сегмент кода 50В2 ргссесаге Статически размещенный в памяти сегмент кода для ЗиЬ Рис. 9.5. Размещение сохраняемых локальных переменных и ссыпки на них Поскольку сегменту кода память выделяется статически и он всегда доступен в процессе выполнения программы, все переменныс, расположенные в той части етого сегмента, который отведен под таблицу локальной среды, также сохраняются во время выполнения программы. Если переменной присвоено начальное значение, например значение 30 для У, то зто начальное значение может быть сохранено в обьекте данных, когда ему отводится некоторое место в памяти (аналогично Сохранение локальных сред.