Концепции языков программирования Имена, связывание, проверка типов и области действия

advertisement
Концепции языков программирования
Имена, связывание, проверка типов и области действия
Концепции языков программирования
Введение
Императивные языки — абстракция архитектуры фон
Неймана
Память
Процессор
Переменные и их атрибуты
Область действия, срок жизни, проверка типов,
инициализация и совместимость типов
Концепции языков программирования
Имена
Вопросы проектирования
Максимальная длина?
Разрешены ли связующие символы?
Должны ли имена быть чувствительны к регистру?
Являются ли специальные слова зарезервированными
или ключевыми?
Концепции языков программирования
Имена
Продолжение
Длина
Слишком короткие имена не информативны
Примеры языков:
FORTRAN I: не более 6
COBOL: не более 30
FORTRAN 90 и ANSI C: не более 31
Ada и Java: нет ограничений, и все символы
принимаются во внимание
C++: нет стандартных ограничений, но реализации
часто вводят собственные ограничения
Концепции языков программирования
Имена
Продолжение
Связки
Не разрешены в языках Pascal, Modula-2 и FORTRAN 77
Разрешены в других языках
Концепции языков программирования
Имена
Продолжение
Чувствительность к регистру
Недостаток: читабельность (схожие имена различны)
в C++ и Java стандартные имена содержат символы из
разных регистров (например,
IndexOutOfBoundsException)
В языках C, C++ и Java имена чувствительны к
регистру
В некоторых других языках — не чувствительны
Концепции языков программирования
Имена
Продолжение
Специальные слова
Способствуют читабельности; ограничивают или
разделяют операторы
Ключевое слово является специальным только в
определенном контексте
Пример (Fortran)
Real VarName (Real — тип данных, за которым следует имя,
поэтому Real — ключевое слово)
Real = 3.4 (Real — переменная)
Недостаток ключевых слов — низкая читабельность
Зарезервированное слово — специальное слово, которое
не может быть использовано в качестве нового
произвольного имени
Концепции языков программирования
Переменные
Переменная — абстракция ячейки памяти
Переменные могут быть описаны при помощи шести
атрибутов: имя, адрес, значение, тип, срок жизни и
область действия
Имена есть не у всех переменных (бывают анонимные
переменные)
Концепции языков программирования
Переменные
Продолжение
Адрес — адрес в памяти, с которым связана переменная
(также называется l-значением)
Переменная может иметь разные адреса в разные
моменты времени при исполнении программы
Переменная может иметь разные адреса в разных местах
программы
Синонимы — переменные, ссылающиеся на один и тот
же участок памяти
Синонимия вредна с точки зрения читабельности
(читатели программы вынуждены помнить о синонимах)
Концепции языков программирования
Переменные
Продолжение
Как создаются синонимы:
Указатели, переменные-ссылки (и через параметры)
Некоторые из прежних оправданий синонимии больше
не работают, например, повторное использование
памяти в языке FORTRAN
Использовать динамическое размещение в памяти
Концепции языков программирования
Переменные
Продолжение
Тип определяет область значений переменных и
множество операций, определенных для значений этого
типа; в случае плавающей точки тип также определяет
точность
Значение — содержимое участка памяти, с которым
связана переменная
Абстрактная ячейка памяти — физическая ячейка или
коллекция ячеек, связанных с переменной
Концепции языков программирования
Понятие связывания
l-значение переменной — ее адрес
r-значение переменной — ее значение
Определение
Связывание — установление ассоциации, например, между
атрибутом и сущностью или между операцией и символом
Определение
Время связывания — время, когда происходит связывание
Концепции языков программирования
Понятие связывания
Продолжение
Возможное время связывания:
Проектирование языка — например, привязка
операторных символов к операторам
Реализация языка — например, привязка типа с
плавающей точкой к представлению
Компиляция — например, привязка переменной к типу в
C или Java
Загрузка — например, привязка переменной языка
FORTRAN 77 (или статической переменной языка C) к
ячейке памяти
Исполнение — например, привязка нестатической
локальной переменной к ячейке памяти
Концепции языков программирования
Понятие связывания
Определение
Связывание является статическим, если оно впервые
происходит перед запуском программы и остается
неизменным на протяжении ее исполнения.
Определение
Связывание является динамическим, если оно впервые
происходит во время исполнения или может измениться во
время исполнения программы.
Концепции языков программирования
Понятие связывания
Продолжение
Привязка к типу
Как указать тип?
Когда происходит связывание?
При статическом связывании тип можно указать при
помощи явного или неявного объявления
Концепции языков программирования
Понятие связывания
Определение
Явное объявление — оператор программы, используемый
для объявления типов переменных
Определение
Неявное объявление — механизм по умолчанию для
указания типов переменных (первое появление переменной в
программе)
В языках FORTRAN, PL/I, BASIC и Perl используются
неявные объявления
За: легкость написания программ
Против: сложность чтения программ (менее
проблематично в языке Perl)
Концепции языков программирования
Понятие связывания
Продолжение
Динамическая привязка к типу (JavaScript и PHP)
Указывается посредством оператора присвоения
Пример (JavaScript)
list = [2, 4.33, 6, 8];
list = 17.3
За: гибкость
Против:
Высокая стоимость (динамическая
проверка типов и интерпретация)
Обнаружение ошибок типов компилятором
затруднено
Концепции языков программирования
Понятие связывания
Продолжение
Вывод типов (ML, Miranda и Haskell)
Типы определяются не на основе оператора присвоения,
а на основе контекста использования
Привязка к памяти и время жизни
Выделение памяти — получение ячейки из пула
доступных ячеек
Удаление — возвращение ячейки в пул
Определение
Время жизни переменной — время, в течение которого она
привязана к конкретной ячейке памяти
Концепции языков программирования
Понятие связывания
Продолжение
Категории переменных по времени жизни
Статические — привязаны к ячейкам памяти до начала
исполнения и остаются привязанными к той же ячейке
во время исполнения
Пример
Все переменные языка FORTRAN 77, статические переменные
языка C
Преимущества: эффективность (прямая адресация),
поддержка подпрограмм «с памятью»
Недостаток: негибкость (невозможна рекурсия)
Концепции языков программирования
Понятие связывания
Продолжение
Категории переменных по времени жизни
Стек-динамические — привязка переменной к памяти
осуществляется при обработке ее объявления
Все атрибуты скалярных переменных кроме адреса
являются статически связанными
Пример
Локальные переменные в подпрограммах языка C и методах
языка Java
Преимущества: допускает рекурсию; бережет память
Недостатки
Дополнительные расходы на выделение и очищение
памяти
Подпрограммы не могут «помнить» историю
собственных вызовов
Неэффективные ссылки (косвенная адресация)
Концепции языков программирования
Понятие связывания
Продолжение
Категории переменных по времени жизни
Явные динамические — размещаются и удаляются с
помощью явных инструкций, задаваемых
программистом и осуществляемых во время исполнения
Доступ только через указатели или ссылки
Пример
Динамические объекты в C++ (с использованием new и delete)
Все объекты в Java
Преимущество: динамическое управление памятью
Недостаток: неэффективно и ненадежно
Концепции языков программирования
Понятие связывания
Продолжение
Категории переменных по времени жизни
Неявные динамические — размещаются и удаляются с
помощью операторов присвоения
Пример
Все переменные в APL; все строки и массивы в языках Perl и
JavaScript
Преимущество: гибкость
Недостатки:
Неэффективно, так как все атрибуты динамические
Отложенное обнаружение ошибок
Концепции языков программирования
Проверка типов
Обобщенное понятие операндов и операторов,
покрывающее подпрограммы и присвоения
Проверка типов гарантирует совместимость типов
операндов и операторов
Совместимый тип — тип, принимаемый оператором, или
тип, который в соответствии с правилами языка может
быть неявным образом преобразован к типу,
принимаемому оператором, кодом, порожденным
компилятором. Это автоматическое преобразование
называется приведением.
Ошибка типа — применение оператора к операнду
неподходящего типа
Концепции языков программирования
Проверка типов
Продолжение
Если привязка к типу — всегда статическая, то проверка
типов почти всегда может быть статической
Если привязка к типу — динамическая, проверка типов
должна быть динамической
Определение
Язык программирования называется сильно типизованным,
если ошибки типов всегда обнаруживаются
Концепции языков программирования
Сильная типизация
Преимущество сильной типизации: позволяет
обнаружить случаи неправильного использования
переменных, приводящие к ошибкам типов
Примеры языков
не FORTRAN 77 : параметры, EQUIVALENCE
не Pascal: вариантные записи
не C и не C++: типы параметров могут не проверяться;
union не проверяется
Ada — почти (кроме UNCHECKED CONVERSION)
(Java — аналогично)
Концепции языков программирования
Сильная типизация
Продолжение
Правила приведения типов влияют на сильную
типизацию: они могут значительно ее ослабить (ср.
C++ и Ada)
Хотя Java включает только половину правил
приведения при присвоении из C++, сильная типизация
в Java гораздо менее эффективна, чем в Ada
Концепции языков программирования
Совместимость типов
Речь идет в основном о структурных типах
Определение
Совместимость типов по именам: типы двух переменных
совместимы, если переменные объявляются одновременно,
или в их объявлениях используется одно и то же имя типа
Легко реализовать, но накладывает слишком сильные
ограничения
Подмножества целых типов не совместимы с целыми
типами
Формальные параметры должны иметь те же типы, что
соответствующие аргументы (Pascal)
Концепции языков программирования
Совместимость типов
Продолжение
Структурная совместимость типов: типы двух
переменных совместимы, если они имеют одинаковые
структуры
Более гибко, но сложнее в реализации
Концепции языков программирования
Продолжение
Есть два структурных типа:
Совместимы ли два типа-записи, если они имеют
одинаковую структуру, но используют разные имена для
полей
Совместимы ли два типа-массива, если они одинаковы
за исключением индексов?
Пример
[1..10] и [0..9]
Совместимы ли два перечислимых типа, если их
компоненты называются по-разному?
С точки зрения структурной совместимости типов нет
различия между типами с одной структурой
Пример
разные единицы скорости, обе — с плавающей точкой
Концепции языков программирования
Продолжение
Примеры языков:
Pascal: обычно структурная, но в некоторых случаях
используются имена (формальные параметры)
C: структурная, кроме записей (struct)
Ada: ограниченная форма совместимости по именам
Производные типы позволяют типам с одинаковой
структурой быть различными
Анонимные типы всегда уникальны, даже здесь:
A, B : array (1..10) of INTEGER
Концепции языков программирования
Область действия
Область действия переменной — операторы, для
которых она является видимой
Нелокальные переменные программного модуля —
переменные, которые видны в модуле, но объявлены в
другом месте
Правила разрешения области действия в языке
определяют, как соотносятся имена и переменные
Концепции языков программирования
Область действия
Продолжение
Статическая область действия
Основана на тексте программы
Чтобы связать имя с переменной, (компилятору) нужно
найти объявление
Процесс поиска: искать объявления сначала локально,
затем во все больших объемлющих областях, до тех пор,
пока не обнаружится объявление для заданного имени
Объемлющие статические области действия для
заданной области действия называются ее статическими
предками; ближайший статический предок называется
статическим родителем
Концепции языков программирования
Область действия
Продолжение
Переменная скрыта, если есть более «близкая»
переменная с тем же именем
В языках C++ и Ada разрешен доступ к этим
«скрытым» переменным
В Ada: unit.name
В C++: class_name::name
Концепции языков программирования
Область действия
Продолжение
Блоки
Метод создания статических областей действия внутри
программных модулей — из языка ALGOL 60
Пример (C и C++)
for (...)
{
int index;
...
}
Пример (Ada)
declare LCL : FLOAT;
begin
...
end
Концепции языков программирования
Область действия
Продолжение
Пример (Статические области действия)
Пусть MAIN вызывает A и B
A вызывает C и D
B вызывает A и E
Концепции языков программирования
Пример статической области действия
MAIN
MAIN
A
C
A
B
D
C
B
D
E
Концепции языков программирования
E
Пример статической области действия
MAIN
A
C
MAIN
B
D
A
E
C
B
D
Концепции языков программирования
E
Статическая область действия
Допустим, спецификация изменилась так, что D должна
получить доступ к каким-то данным в B
Решения:
Поместить D в B (но тогда D больше не сможет
вызывать C и потеряет доступ к переменным в A)
Переместить данные, нужные D, из B в MAIN (но тогда
все процедуры получат к ним доступ)
Та же проблема с доступам к процедурам
Вывод: статические области действия часто вынуждают
вводить глобальные переменные
Концепции языков программирования
Область действия
Продолжение
Динамическая область действия
Основана на последовательности вызовов программных
единиц, а не на их текстуальном расположении
(временной подход вместо пространственного)
Связывание ссылок на переменные с объявлениями
осуществляется поиском в обратном направлении по
цепи вызовов подпрограмм, которая привела в заданную
точку
Концепции языков программирования
Пример области действия
MAIN
- !"#$%&'()' x
SUB1
- !"#$%&'()' x ...
%*+!% SUB2
...
SUB2
...
- ,,*&-. (. x ...
...
call SUB1
…
MAIN вызывает SUB1
SUB1 вызывает SUB2
SUB2 использует x
Концепции языков программирования
Пример области действия
Статическая область действия
Ссылка на x относится к x из MAIN
Динамическая область действия
Ссылка на x относится к x из SUB1
Оценка динамических областей действия
Преимущество: удобство
Недостаток: плохая читабельность
Концепции языков программирования
Область действия и время жизни
Область действия и время жизни иногда тесно связаны,
но являются разными понятиями
Пример: static переменная в функции C или C++
Концепции языков программирования
Среды ссылок
Определение
Среда ссылок оператора — коллекция всех имен, видимых
для этого оператора
В языке со статическими областями действия —
локальные переменные и все видимые переменные во
всех объемлющих областях действия
Подпрограмма активна, если ее выполнение началось,
но еще не окончилось
В языке с динамическими областями действия среда
ссылок — локальные переменные и все видимые
переменные во всех активных подпрограммах
Концепции языков программирования
Именованные константы
Определение
Именованная константа — переменная, которая связывают
со значением, только когда ее связывают с участком памяти
Преимущества: легкость чтения и изменения программы
Используются для параметризации программ
Связывание значений с именованными константами
может быть статическим (константы манифеста) или
динамическим
Языки:
Pascal: только литералы
FORTRAN 90: константные выражения
Ada, C++, и Java: выражения любого вида
Концепции языков программирования
Инициализация переменных
Определение
Связывание переменной со значением в момент, когда она
связывается с участком памяти, называется инициализацией
Инициализация часто осуществляется в объявлении
Пример (Java)
int sum = 0;
Концепции языков программирования
Резюме
Чувствительность к регистру и отношение между
именами и специальными словами — вопросы
проектирования, относящиеся к именам
Переменные характеризуются шестью параметрами:
имя, адрес, значение, тип, время жизни, область
действия
Связывание — это присвоение атрибутов программным
сущностям
Скалярные переменные подразделяются на:
статические, стек-динамические, явно динамические,
неявно динамические
Сильная типизация подразумевает обнаружение всех
ошибок типов
Концепции языков программирования
Download