Cтраница 2
Специальные приемы программирования 6.9.6.1. Обмен данными между подпрограммами через общие области памяти. Процедуры и функции могут модифицировать внешние переменные двумя способами: через свои параметры или непосредственным обращением к глобальным идентификаторам. В последнем случае вполне возможна ситуация, когда несколько подпрограмм модифицируют одну и ту же глобальную переменную. [16]
Уровень 2 стандарта IS 9660 разрешает использовать имена файлов длиной до 32 символов, а уровень 3 позволяет использовать сегментированные файлы. Расширения стандарта Rock Ridge ( прихотливо названное в честь города в фильме Джина Уайлдера Blazing Saddles) разрешают использовать очень длинные имена ( для UNIX), а также универсальные идентификаторы UID, глобальные идентификаторы GID и связывание файлов. Однако CD-ROM, не удовлетворяющие уровню 1 стандарта IS 9660, могут оказаться нечитаемыми на многих компьютерах. [17]
Что касается процедуры С, то идентификатор ОР в ней вообще не описав. Однако если в теле процедуры С есть операторы, использующие этот идентификатор ОР, то значение и смысл его берутся такими, какими они определены в начале блока, представляющего собой программу. Таким образом, процедура С изменяет значение глобального идентификатора. [18]
Первое появление идентификатора в программе всегда происходит в описании, в котором идентификатор определяется. Идентификатор затем используется до тех пор, пока где-нибудь в программе он не станет неопределенным. Идентификатор, остающийся определенным до конца программы, называется глобальным идентификатором. Если идентификатор становится неопределенным раньше, чем кончается программа, он называется локальным идентификатором. Поэтому в примерах каждый идентификатор будет определен от точки, где он описан, до конца программы. [19]
Все прочие идентификаторы, встречающиеся в этом блоке, считаются в нем глобальными. Каждый глобальный идентификатор должен быть локальным в одном из блоков, охватывающих данный блок. Таким образом, в самом внешнем блоке Алгол-программы не может быть глобальных идентификаторов. Напомним, однако, что для идентификаторов, закрепленных за стандартными функциями и за некоторыми другими объектами, допускается исключение из этого правила. Локальные идентификаторы блока становятся глобальными в его подблоках, если в последних не локализованы такие же идентификаторы. Локализация одного и того же идентификатора в разных блоках допускается как в случае непересекающихся блоков, так и в случае, когда один из блоков целиком вложен в другой. При этом в каждом из таких блоков идентификатор представляет свой объект, недоступный другому блоку. [20]
Все прочие идентификаторы, встречающиеся в этом блоке, считаются в нем глобальными. Каждый глобальный идентификатор должен быть локальным в одном из блоков, охватывающих данный блок. Таким образом, в самом внешнем блоке АЛГОЛ-программы не может быть глобальных идентификаторов. Напомним, однако, что для идентификаторов, закрепленных за стандартными функциями и за некоторыми другими объектами, допускается исключение из этого правила. Локальные идентификаторы блока становятся глобальными в его подблоках, если в последних не локализованы такие же идентификаторы. Локализация одного и того же идентификатора в разных блоках допускается как в случае непересекающихся блоков, так и в случае, когда один из блоков целиком вложен в другой. При этом в каждом из таких блоков идентификатор представляет свой объект, недоступный другому блоку. [21]
Идентификаторы, используемые в блоке, но не локализованные ( не описанные) в нем, называются глобальными для данного блока. Такие идентификаторы имеют один и тот же смысл как внутри данного блока, так и вне его. Другими словами, новая система обозначений, вводимая блоком, затрагивает только описанные в нем идентификаторы; по отношению же к глобальным идентификаторам блок эквивалентен составному оператору, так что они представляют объекты, общие для разных блоков - тем самым и осуществляется их взаимная связь. [22]
При этом значение л и значения компонент матрицы а должны быть определены до входа в данный блок, а потом они могут использоваться вне его. На рассматриваемом этапе вычислений введены в употребление шесть новых объектов, которые используются только на этом этапе. В описаниях, приведенных в начале блока, указана информация об этих объектах и каждому из них дано свое наименование, причем для этих целей можно взять любые отличные друг от друга шесть идентификаторов, кроме глобальных идентификаторов а, п, Р, Q и 11, которые внутри данного блока должны сохранить тот же смысл, что и вне его. [23]
Функции формальных параметров по передаче в тело процедуры значений исходных величин и получению результата в процедуре без параметров выполняются глобальными идентификаторами. Поэтому перед обращением к процедуре без параметров глобальным идентификаторам, обозначающим исходные величины, должны быть присвоены требуемые значения. При обращении к процедуре без параметров указывается лишь один идентификатор процедуры. Результат выполнения процедуры присваивается в ее теле соответствующим глобальным идентификаторам, которые и используются после обращения к процедуре в последующих действиях. [24]
Можно заключить, что решение о том, пользоваться ли нелокальными идентификаторами, должно приниматься в зависимости от конкретной задачи. Выдвинутая здесь аргументация не применима к программе длиной в сотни страниц. Многие преподаватели программирования с гораздо большим усердием, чем мы в этой книге, доказывают, что использование нелокальных идентификаторов всегда плохо. На самом деле, однако, оказывается, что большинство нетривиальных программ имеют глобальные идентификаторы, причем в результате они оказываются более наглядными. [25]
Перемещающий ассемблер и связывающий загрузчик решают эти задачи следующим образом. Во-первых, ассемблер производит объектный код в предположении, что начальный адрес каждой программы равен нулю. Во-вторых, он отмечает каждый относительный адрес или слово данных таким образом, что загрузчик будет знать, на какие части программы влияет перемещение. В-третьих, в ассемблере предусмотрена для программиста возможность объявления некоторых идентификаторов глобальными. Глобальный идентификатор объявляется либо в данной программе меткой или оператором прямого присваивания, либо это может быть сделано в другой программе, транслируемой отдельно. В первом случае глобальный символ называется идентификатором входа, а во втором - внешним идентификатором. [26]
Совокупность формальных параметров состоит из списка формальных параметров, заключенного в круглые скобки. После совокупности формальных параметров ( а при ее отсутствии - после идентификатора процедуры) ставится точка с запятой. В списке они разделяются запятыми. Глобальный идентификатор, встречающийся в теле процедуры, считается формальным параметром лишь в том случае, когда он включен в список формальных параметров. [27]
Переменной актигра и процедуры читайигру в блоке лото просто нет, и поэтому нам вовсе незачем ломать голову, когда мы записываем этот блок, хотим его понять или изменить. В процедуре читайкар-точку эти объекты есть, но и процедура читайигру тоже имеет собственные локальные описания, а именно: ищицифрувтойжестроке и актпозиция. Так что понятия локальный и глобальный следует воспринимать всегда относительно - по отношению к определенному блоку. То, что для процедуры чи-тайкарточку является локальным, для процедуры читайигру уже глобальное. Беспрепятственной работе разных процедур способствует еще одно правило: если локальное описание дает новое значение идентификатору, уже известному как глобальный идентификатор, то глобальная величина в соответ. [28]
Для этого следует остановиться на двух вопросах. Первый вопрос касается порядка размещения описаний в блоках. Subset Algol 60 запрещает использование любого идентификатора раньше ( если просматривать запись слева направо), чем будет закончено его описание, за исключением идентификатора, представляющего метку, и идентификатора процедуры, когда он используется в левых частях операторов присваивания. Это означает, в частности, что в теле какой-либо процедуры не может быть явно указано обращение к этой же процедуре, а также не могут использоваться глобальные идентификаторы, описываемые вслед за описанием данной процедуры. [29]
В основе типичной реализации АПЛ лежит чисто программ-ная интерпретация выполняемой программы. Программы хранятся по существу в том виде, в котором вводятся, подвергнувшись лишь минимальной трансляции. Выделяются две статические области памяти: одна для системных программ и одна для рабочей области, используемой программистом в данный момент. С системными программами обычно работают сразу несколько пользователей, однако у каждого из них имеется своя собственная рабочая область. Память, выделяемая под рабочую область, включает статическую подобласть, содержащую системные данные и три динамические подобласти: стек для записей активаций подпрограмм ( локальные среды ссылок и точки возврата), куча для массивов и тел определений подпрограмм и таблица ассоциаций для глобальных идентификаторов. Когда необходимо, выполняется сбор мусора и полное уплотнение памяти. Для хранения массивов применяется обычное последовательное представление с полными дескрипторами, используемыми во время выполнения программы. [30]