Р.У. Себеста - Основные копцепции языков программирования (2001) (1160794), страница 52
Текст из файла (страница 52)
Рассмотрим. например, следующие обьявления: суре суре1 = аккау [1 .. 10] ок Ьпс едет; Гуре2 = актау [ 1.. 10] ок 1пкедегз суреЗ = суре2г В этом примере типы суре1 и Суре2 несовместимы, что свидетельствует об использовании совместимости структур типов. Более того, тип .уре2 совместим с типом суреЗ, из чего можно заключить, что эквивалентность имен также не используется строго. Такая форма совместимости иногда называется эквивалентностью объявлений (бес!агайоп ег[ц[ка!епсе), поскольку при определении типа с помощью имени другого типа, оба они являются совместимыми, даже если они несовместимы по именам типов.
В языке Аг]а используется совместимость имен типов, но при этом имеются две конструкции — подтипы и производные типы, — позволяющие устранить проблемы, возникающие при этом виде совместимости. Производным (с[егвед) называется новый тип, основанный на некотором ранее определенном типе, с которым он несовместим, несмотря на то, что они имеют идентичную структуру. Производные типы наследуют все свойства родительских типов.
Рассмотрим следующий пример: Фу]рв се1вуца хв пвм ГЬОРТг су]рв 1айгеп[те1с Лв пан ГЬОАТг Переменные данных типов несовместимы, хотя и имеют идентичную структуру. Более того, переменные этих типов несовместимы ни с каким другим типом чисел с плавающей точкой. Исключением из правила являются только литеральные константы. Литеральная константа, например 3. О, имеет тип универсальных дейспщтельных чисел и совместима с любым типом чисел с плавающей точкой.
Производные типы также могут содержать ограничения диапазона родительского типа, наследуя при этом все его операции. Подтнп (зцЬгуре) в языке Аба — версия существующего типа с возможно ограниченным диапазоном. Подтип совместим с породившим его типом. Рассмотрим следующее объявление: виЬФу]рв ЯИАЬЬ ТУРЕ Ев 1[ЗТЕОЕК капдв 0..99; Переменные, имешие тип ЕМАЬЬ ТУРЕ, совместимы с переменными, имеющими тип 1МТЕОЕК.
Правила совместимости типов в языке Аба более важны, чем соответствующие правила языков. в которых широко используется приведение типов. Например, два операнда, входящие в оператор сложения в языке С, могут иметь практически любую комбинацию числовых типов этого языка. Один из операндов при этом просто приводится к типу лругого. Однако в языке Ада нет приведения типов операндов арифметического оператора. В языке С используется структурная эквивалентность для всех типов, за исключением структур (записи языка С) и объединений, для которых используется эквивалентность обьявлений.
Правда, если две структуры илн объединения определяются в двух различных файлах, используется эквивалентность типов структур. 4.7. Совместимость типов В языке С~+ используется эквивалентность имен. Отметим, что оператор курос(еу языков С и С++ не вводит новый тип. Он просто определяет новое имя для уже существующего типа. Во многих языках переменные могут объявляться без использования имен типа, создавая безымянные типы.
Рассмотрим следующий пример из языка Ада: А: вгхву (1 .. 10) ог 1)(ТЕРЕКг В этом случае переменная А имеет безымянный, но неоднозначно определенный тип. В обьявлении В: вггву (1 .. 10) оЕ 1)(ТЕСЕ)() переменные А и В будут принадлежать к безымянным, но различным и несовместимым типам, хотя они имеют идентичную структуру. Множественное объявление С, Р: вггву (1 ..
10) ог' 1)(ТЕЯЕВг создаст два безымянных типа: один лля переменной С, другой — для переменной Р, несовместимых между собой. Фактически эти объявления можно рассматривать как следующие лва объявления: С: вггву (1..10) ос |НТЕРЕПг Р: вггву (1.. 10) ог 1)(ТЕРЕВ; Результатом этого будет несовместимость переменных С и Р. Однако в объявлении Суре ЫЯТ 10 Ев вггву (1..10) оЕ 1ЫТЕРЕКг С, Р: ЫЯТ 10) переменные С и Р будут совместимыми.
Очевилио, что в языках, не позволяющих пользователям определять и называть типы, например РОСТКАХ и СОВОЬ, эквивалентность имен использоваться не может. Возникновение таких объектно-ориентированных языков, как )ата и С++, подняло вопрос о другом типе совместимости типов. Это — вопрос о совместимости обьектов и его связи с иерархией наследования. Подробнее об этом рассказывается в главе ().
Совместимость типов в выражениях рассмотрена в главе 6; совместимость типов параметров подпрограмм описана в главе 8. 4.8. Область видимости Одной из важнейших характеристик переменных является область видимости. Область видимости (зсоре) переменных программы — это ряд операторов, в которых переменная видима. Переменная является видимой (тюЫе) в операторе, если к переменной, входящей в оператор, можно обратиться. Правила обзора данных в языке определяют, как именно конкретное появление имени связано с переменной.
В частности, правила обзора данных определяют, каким образом ссылки на переменные, объявленные вне выполняющейся в данный момент подпрограммы или блока, связаны с их объявлениями н, вследствие этого, с их атрибутами (блоки рассматриваются в разделе 4.8.2). Следовательно, для написания или чтения программ на данном языке необходимо полное знание этих правил. 1Р2 Глава 4.
Имена, связывание, проверка типов и области видимости Как определялось в разлеле 4.4.3.2. переменная является локальной в программной единице или блоке, если она там объявлена. (В данной главе мы считаем программными единицами главный программный модуль или подпрограммы. Единицы. подобные классам языков С++ или )ача. рассматриваются в главе )О,) Нелокальными переменными (поп)оса! тат)аЫея) программной единицы или блока называются переменные. которые вилнмы в этой программной единице нли блоке, но не объявляются в них. 4.8.1. Статическая область видимости В языке АЕООЕ 60 был введен метол связывания имен с нелокальными переменными, названный статическим обзором данных (ьтабс асор)пб). Позже этот метод был позанмствован большинством императивных, а талже многими неимперативными языками.
Использование статического обзора ланных получило свое название из-за возможности статического (т.е. до периода выполнения) определения области видимости любой переменной. Большинство отдельных статических областей видимости в императивных языках связаны с определениями программных единиц. Прелположим. что все области видимости связаны с программными единицами.
В данной главе мы также будем полагать. что для обращения к нелокальным переменным в обсуждаемых языках используются только области видимости. Последнее не совсем справедливо даже для языков со статическим обзором данных, но такое предположение упрощает обсуждение. Дополнительные методы обращения к нелокальным переменным рассматриваются в главе 8. Во многих языках подпрограммы создают собственные области видимости.
Во всех распространенных языках со статическим обзором данных, за исключением языков С, С++, Зата и ГОКТЙАМ, подпрограммы могут вклалываться в другие подпрограммы, что создает в программе иерархию областей видимости. Когда в языке, использующем статический обзор данных, компилятор обнаруживает переменную, ее атрибуты опрелеляются путем поиска объявившего ее оператора. В языках, использующих статический обзор данных, при наличии вложенных подпрограмм этот процесс протекает следующим образом.
Предположим, что сделано обращение к переменной х полпрограммы вцЬ1. Соответствующее объявление вначале разыскивается в обьявлениях подпрограммы виЬ1. Если для данной переменной объявления не найдено, то поиск прололжается в объявлениях подпрограммы, объявившей полпрограмму вць1. называемой статическим родителем (ма!ге рагеп!) полпрограммы вць1. если объявление переменной х не найдено и в этой подпрограмме.
то поиск продолжается в следующей внешней единице (в модуле, объявившем родителя подпрограммы вцЬ1) и так далее, пока не будет найдено объявление переменной х, или поиск в самом внешнем блоке не увенчается успехом. В последнем случае будет зафиксирована ошибка необьявленной переменной. Статический родитеяь подпрограммы виЬ1, его статический родитель и так далее вплоть до основной программы называются статическими предками (мабс апсемогя) подпрограммы вць1. Отметим, что методы реализации статического обзора данных, рассматриваемые в главе 9, значительно эффективнее, чем только что описанный процесс. Рассмотрим слелуюшую процедуру языка Рааса); ркосасзцкв Ьзд; чае х : 1пседег; ркооес(цка виЬ1; Ьид5.п ! вцЬ1 ) 4.8.