Т. Пратт, М. Зелковиц - Языки программирования - разработка и реализация (4-е издание_ 2002) (1160801), страница 54
Текст из файла (страница 54)
Также это объявление связывает объекты данных с именами А и В на период времени их жизни. Приведенное выше объявление языка С называется ясным обьявлеяием. Во многих языках используются также неявные объявления, илп обънвле~ия по умолчанию. Они вступают в силу только в том случае, если отсутствуют явные объявления. Например, в подпрограмме а языке РОтяТтяАЬ7 можно использовать простую переменную с именем 77тВЕя', не объявляя се явным образом, — по умолчанию компилятор предполагает, что эта переменная имеет целочисленный тип, так как ее имя начинается с буквы из диапазона [-Х.
В языке Рег! объявление псреэиенной происходит, когда ей присваивается некоторое значение: таас - 'в ввг1па'. 77 таас — странавая перененная Ъаьс - 7: 7)т теперн аЬс — непаннспеннвя перененная В обьявлении также можно задать значение объекта данных, если это константа, или начальное значение объекта данных, если он не является константой. В объявлении также могут быть указаны другие виды связываний для данного объекта: имя объекта или его размещение как компонента внутри другого, более крупного, объекта даяных. Иногда в объявлении указываются и некоторые детали, относящиеся к реализации объекта: связывание с конкретным месте вложением в памяти или с конкретной формой представления обьскта. Например, используемый в языке СОВО! модификатор СОМРВТАНОйАЬ для целых чисел обычно указывает на необходимость использонапна лвоичнопя (а не символьного) представления зна 7ений этих объектов в памяти, что позволяет ищюльзовать более;х(эфсктивпыс арифметические операции.
194 Глава 5. Элементарные типы данных Объявление операций Информация, которая в процессе трансляции требуется в первую очередь, — это сигнатура каждой операции. Обычно для встроенных в язык, то есть элементарных, операций явное объявление типов аргументов и результата не требуется. Эти операции можно вызывать по мере надобности, а типы аргументов и результатов для них по умолчанию определяются транслятором языка, Но для определяемых программистом операций обычно следует сообщить транслятору о типах аргументов и результатов перед тем, как обращаться к подпрограмме. Например, в языке С эта информация помещается в заголовочную часть определения подпрограммы, ее прототип.
Так, следующий прототип П оат 5оЬЫ пт Л 11оае П объявляет подпрограмму 5оЬ со следуюнгей сигнатурой: 5о1ц 1пт х Поат -> Ыоат Функции объявлений Обьявления выполняют несколько важных функций. 1. Выбор способа предппавггения в памяти. Если объявление содержит сведения о типе данных и атрибутах объекта данных, то на основе этой информации транслятор часто может оптимизировать представление этого объекта данных в памяти, 2. Улучшение управления памятью, Содержащаяся в объявлении информация о времени жизни объектов данных зачастую позволяет использовать более эффективные процедуры управления памятью во время выполнения программы. Например, в языке С все объекты, объявленные в начале подпрограммы, имеют одинаковое время жизни (равное времени выполнения подпрограммы) и, следовательно, могут быть расположены в едином блоке памяти, который создается при входе в подпрограмму и уничтожается при выходе из нее.
Другие обьекты данных в С создаются динамически посредством специальной функпии ва11ос. Поскольку для таких объектов время жизни не указано, каждому такому объекту место в памяти отводится индивидуально. 3. Полиморфные операции. В большинстве языков используются спепиальные символы для обозначения некоторых основных операций; так, например, символ «+ > может обозначать любую из нескольких операций сложения в зависимости от типа переданных аргументов, Например, в С запись А + В может обозначать «выполнить целочисленное сложение >, если А и В при надлежат целочисленному типу, или «выполнить вещественное сложение», если А и  — вещественные числа.
В этом случае говорят, что символ операции является перегруясеннмм, так как он обозначает не одну конкретную операцию, а скорее некоторую обгцую операцию сложения (определяющую группу родственных операций), которая может иметь разные формы для аргументов разных тинов. В большинстве языков основные символы операций, такие как «, ' и г, являются перегруженными (то есть они обозначают общие операции); другие имена операций определяют операции однозначным образом. Но, например, в языке Лпа программист имеет возможность опре- 5.1.
Свойства типов и объектов 195 делять перегружаемые имена подпрограмм и добавлять дополнительный смысл существующим символам операций. В языке МЕ концепция полиморфизма получила полную реализацию, в которой одно и то жс имя функции может быть использовано для многих ее реализаций, зависящих от типа передаваемых аргументов. Если говорить об объектно-ориентированных языках, то полиморфизм является главным свойством, которое позволяет программисту расширить язык програл~л~ирования с помогцью новых типов данных и операций. Объявления обычно позволяют колшилятору языка определить во время компиляции, какая именно из группы родственных операций, обозначенных перегруженным символом, подразумевается в каждом конкретном случае. Например, в языке С на основе объявлений переменных А и й компилятор определяет, какая из двух возможных операций (целочпсленное или вещественное сложение) подразумевается в записи А + В.
В таком случае не требуется проверки соответствия типов при выполнении программы. В языке Вша!1га!К напротив, требуется определять конкретный вид операции сложения каждый раз, когда при выполнении программы встречается символ елгь поскольку в этол~ языке отсутствуют объявления типов для переменных. 4. Контроль типов, С точки зрения программиста, наиболее ценным свойством объявлений является то, что они позволяют производить статический, а не динамический контроль типов.
5.1.4. Контроль типов и преобразование типов Способы представления даннъ1х, поддерживаемых аппаратной частью компьютера, обычно не предусматривают включение информации о типе данных, а при выполнении элементарных операций над такими данными контроль типов пе осуществляется. Например, некоторое слово в памяти компьютера во время выполнения программы может содержать последовательность бнт 11100101100...0011. Эта последовательность может представлять собой целое число, вещественное число, цепочку литер или инструкцию процессора — не существует способа определить, что именно, Элементарная операция целочисленного сложения, встроенная в аппаратную часть компьютера, не может проверить, являются ли переданные ей два аргумента целыми числами, — для нее это просто последовательности битов.
Таким образом, на уровне аппаратуры обычные компьютеры весьма ненадежны в плане обнаружения ошибок в типах данных. Контроль типов означает проверку того, что каждая операция, выполняемая в программе, получает правильное количество аргументов правильного типа. Например, перед выполнением оператора присваивания А+В*С компилятор должен проверить, что каждая операция (умножение, сложение ц присваивание) получает по два аргумента правильного типа. Если операция сложения + определена только для целых или вещественных чисел, а А принадлежит к символьному типу данных, то произойдет ошибка в типе аргумента. Контроль типов 196 Глава 5. Элементарные типы данных может происходить во время выполнения программы (динамический хоиглроль типов) или во время компиляции (статический кошлроль типов). Значительное преимугцество использования в программировании языков высокого уровня объясняется тем, что в реализации таких языков предусмотрен контроль типов для всех (или почти всех) операций и таким образом программист оказывается зшпищсн от этого весьма трудноуловимого вида ошибок.
Динамический контроль типов для аргументов некоторой операции осуществляется во время работы программы нешюредственно перед выполнением данной операции. Реъчизацпя динамического контроля обычно основана на использовании дескриптора типа, который хранится вместе с объектом данных и указывает его тип.
Например, в целочисленном обьектс данных содержится и его значение, и дескриптор, указывающий на принадлеж~шсть ооъскта к целочисленному типу. Тогда каждая операция реализуется таким образом, чтобы в первую очередь проверялся дсск(шптор типа каждого аргумента. Операция выполняется, только если типы аргументов правильны; в противном случае генерируется сообщение об ошибке. После того как получен результат операции, к нему тоже должен быть присоединен соответствующий дескриптор, описывающий его тип, чтобы операции, в которых впоследствии этот объект может участвовать в качестве аргумента, могли бы проверить его тип.
Некоторыс языки программирования, например Рег! и Рго!оц, разработаны таким образом, что для них необходим динамический контроль типов. В этих языках не используется явное объявление типов переменных и отсутствуют встроенные (неявные) объявления типов (в отличие от языка ГО КТКЛ1ч, в котором переменные объявляются по умолчанию). Тиц переменных А и В в выражении А ~ В может меняться в процессе выполнения программы. В такой ситуации динамический контроль типов этих переменных необходим для каждой операции сложения, происходящей во время выполнения программы. В таких языках, гле отсутствуют объявления, переменные называются не имеющими типа, или бестиповылш, так как у них действительно нет никакого фиксированного типа.