Добавлен: 20.05.2023
Просмотров: 252
Скачиваний: 2
СОДЕРЖАНИЕ
Есть несколько подходов реализующих модель метапрограммирования:
Генерация кода – при этом подходе код программы не пишется вручную, а создается автоматически программой-генератором на основе другой, более простой программы. Реализуется двумя основными методами:
Шаблоны. Решают задачу, если соблюдение «правил» сводится к вставке в программу повторяющихся (или почти повторяющихся) кусков кода. Помимо этого, обладают еще рядом достоинств: например, помогают повторному использованию.
Внешне-языковые средства. Применяются в случаях, если простых средств вроде шаблонов недостаточно. Язык генератора составляется так, чтобы автоматически или с минимальными усилиями со стороны программиста реализовывать правила парадигмы или необходимые специальные функции. Фактически, это – более высокоуровневый язык программирования, а генератор – не что иное, как транслятор. Генераторы пишутся, как правило, для создания специализированных программ, в которых очень значительная часть стереотипна, либо для реализации сложных парадигм.
Основные парадигмы и подходы к решению задач в современных языках программирования представлены в таблице 2.
Таблица 2 Парадигмы и подходы языков программирования
|
Язык программирования |
Парадигмы программирования |
Основные подходы программирования |
|
Java |
императивная структурная |
объектно-ориентированный |
|
C |
императивная |
процедурный |
|
C++ |
мультипарадигмальный метапрограммирование |
процедурный объектно-ориентированный |
|
C# |
мультипарадигмальный императивная |
процедурный объектно-ориентированный |
|
Python |
императивная декларативная структурная |
процедурный функциональный объектно-ориентированный |
|
Visual Basic.NET |
императивная структурная |
процедурный объектно-ориентированный |
|
PHP |
мультипарадигмальный |
процедурный объектно-ориентированный |
|
JavaScript |
императивная структурная |
объектно-ориентированный |
|
Delphi/Object Pascal |
императивная структурная |
процедурный объектно-ориентированный |
|
Swift |
мультипарадигмальный |
процедурный объектно-ориентированный |
Современные языки программирования не ограничиваются какой-то одной парадигмой, а используют их несколько или даже являются мультипарадигмальными. Это обусловлено стремлением разработчиков расширить области применения языка, сделать его языком общего назначения, а не ориентированным на решение узкого круга задач.
Использование почти всеми языками объектно-ориентированного подхода наряду с «классическим» процедурным, обусловлено возрастающей сложностью современных задач. Создание больших распределенных систем просто не мыслимо без создания структурной модели, а работа с объектами, в любых их проявлениях, значительно облегчает разработку и отладку таких систем
3. Трансляторы
Поскольку текст, записанный на языке программирования, непонятен компьютеру, то требуется перевести его на машинный код. Такой перевод программы с языка программирования на язык машинных кодов называется трансляцией, а выполняется она специальными программами – трансляторами.
Транслятор – обслуживающая программа, преобразующая исходную программу, предоставленную на входном языке программирования, в рабочую программу, представленную на объектном языке.
В настоящее время трансляторы разделяются на две основные группы: компиляторы и интерпретаторы.
3.1 Компилятор
Компилятор – это обслуживающая программа, выполняющая трансляцию на машинный язык программы, записанной на исходном языке программирования. Компилятор обеспечивает преобразование программы с одного языка на другой (чаще всего, в язык конкретного компьютера). Вместе с тем, команды исходного языка значительно отличаются по организации и мощности от команд машинного языка. Существуют языки, в которых одна команда исходного языка транслируется в 7–10 машинных команд. Однако есть и такие языки, в которых каждой команде может соответствовать 100 и более машинных команд. Кроме того, в исходных языках достаточно часто используется строгая типизация данных, осуществляемая через их предварительное описание. Программирование может опираться не на кодирование алгоритма, а на тщательное обдумывание структур данных или классов. Процесс трансляции с таких языков обычно называется компиляцией, а исходные языки обычно относятся к языкам программирования высокого уровня (или высокоуровневым языкам).
3.2 Интерпретатор
Интерпретатор – программа или устройство, осуществляющее пооператорную трансляцию и выполнение исходной программы. Интерпретатор не порождает на выходе программу на машинном языке. Распознав команду исходного языка, он тут же выполняет ее. Простой интерпретатор – анализирует и тут же выполняет (собственно интерпретация) программу покомандно (или построчно), по мере поступления исходного кода на вход интерпретатора. Достоинством такого подхода является мгновенная реакция. Недостаток – такой интерпретатор обнаруживает ошибки в тексте программы только при попытке выполнения команды (или строки) с ошибкой. Интерпретатор компилирующего типа – это система из компилятора, переводящего исходный код программы в промежуточное представление, например, в байт-код или p-код, и собственно интерпретатора, который выполняет полученный промежуточный код (так называемая виртуальная машина). Достоинством таких систем является бо́льшее быстродействие выполнения программ (за счёт выноса анализа исходного кода в отдельный, разовый проход, и минимизации этого анализа в интерпретаторе). Недостатки – большее требование к ресурсам и требование на корректность исходного кода.
Достоинства интерпретаторов:
– Большая переносимость интерпретируемых программ – программа будет работать на любой платформе, на которой есть соответствующий интерпретатор. Как правило, более совершенные и наглядные средства диагностики ошибок в исходных кодах.
– Упрощение отладки исходных кодов программ. Интерпретатор позволяет начать обработку данных после написания даже одной команды.
– Меньшие размеры кода по сравнению с машинным кодом, полученным после обычных компиляторов.
Недостатки интерпретаторов:
– Интерпретируемая программа не может выполняться отдельно без программы–интерпретатора. Сам интерпретатор при этом может быть не очень компактным.
– Интерпретируемая программа выполняется медленнее, поскольку промежуточный анализ исходного кода и планирование его выполнения требуют дополнительного времени в сравнении с непосредственным исполнением машинного кода, в который мог бы быть скомпилирован исходный код.
– Практически отсутствует оптимизация кода, что приводит к дополнительным потерям в скорости работы интерпретируемых программ.
Виды трансляторов современных языков программирования представлены в таблице 3.
Таблица 3 Трансляторы современных языков программирования
|
Язык программирования |
Транслятор |
|
Java |
компиляция в байт-код интерпретатор |
|
C |
компилятор |
|
C++ |
компилятор |
|
C# |
компилятор |
|
Python |
компиляция в байт-код интерпретатор |
|
Visual Basic.NET |
компиляция в MSIL-код интерпретатор, компилятор |
|
PHP |
компиляция в байт-код интерпретатор |
|
JavaScript |
компиляция в байт-код интерпретатор |
|
Delphi/Object Pascal |
компилятор |
|
Swift |
компиляция в байт-код интерпретатор |
Современные языки программирования используют в равной степени компиляцию и интерпретацию.
Широкое использование компиляторов обусловлено большой скоростью работы программ, а также возможность использовать полностью все возможности конкретных платформ и создание «машинно-зависимых» участков кода и программ.
Использование интерпретации, напротив, позволяет оградить программиста от особенностей конкретных платформ, что наиболее востребовано в связи с развитием Интернет–технологий.
Среди интерпретируемых языков используются в основном интерпретаторы компилирующего типа, что обусловлено значительным увеличением скорости работы программ в сравнении с простыми интерпретаторами. При разработке больших и сложных приложений такое увеличение скорости может быть очень существенным.
4. Типизация данных
Тип – относительно устойчивая и независимая совокупность элементов, которую можно выделить во всём рассматриваемом множестве.
Математически тип может быть определён двумя способами:
Множеством всех значений, принадлежащим типу.
Предикатной функцией, определяющей принадлежность объекта к данному типу.
Тип данных – фундаментальное понятие теории программирования. Тип данных определяет множество значений, набор операций, которые можно применять к таким значениям и, возможно, способ реализации хранения значений и выполнения операций. Любые данные, которыми оперируют программы, относятся к определённым типам.
Типы данных различаются уже на нижних уровнях системы. Так, например, даже в Ассемблере х86 различаются типы «целое число» и «вещественное число». Это объясняется тем, что для чисел рассматриваемых типов отводятся различные объёмы памяти, используются различные регистры микропроцессора, а для операций с ними применяются различные команды Ассемблера и различные ядра микропроцессора.
В языках программирования типы данных не всегда строго соответствуют подобным математическим типам. Например, тип “целое число” большинства языков программирования не соответствует принятому в математике типу “целое число”, так как в математике указанный тип не имеет ограничений ни сверху, ни снизу, а в языках программирования эти ограничения есть. Как правило, в языках и системах имеется множество целых типов, отличающихся допустимым диапазоном значений (определяемым объёмом занимаемой памяти).
Наиболее часто используемые типы данных:
Простые:
Перечислимый тип. Хранит значения, прямо указанные в его описании.
Целочисленный тип. Целое число со знаком и без знака.
Вещественный тип. Вещественное число с запятой и с плавающей точкой.
Символьный тип. Хранит один символ в различных кодировках.
Множество. Совпадает с обычным математическим понятием множества.
Логический тип. Принимает два значения ложь = 0 и истина = 1.
Указатель. Хранит адрес в памяти, указывающий на какую–либо информацию, как правило – указатель на переменную.
Составные (сложные):
Массив. Хранит индексированный набор элементов одного типа.
Строковый тип. Хранит строку символов.
Запись (структура). Набор различных элементов (полей), хранимый как единое целое.
Файловый тип. Хранит только однотипные значения, доступ к которым осуществляется только последовательно.
Класс, метакласс, интерфейс. Абстрактные типы данных в объектно–ориентированном программировании (ООП).
Как уже отмечалось ранее, любой тип данных в языках программирования определяет не только множество собственных значений, но и набор операций, способы хранения и присваивания значений. Типы переменных и параметров должны совпадать с присваиваемыми им значениями или вызываемыми для них функциями. Для обеспечения совместимости типов переменных и их значений в языках программирования существует контроль типов (типизация) – это процесс проверки и накладывания ограничений на использование типов.
Существует два вида контроля типов:
Статическая типизация – при которой переменная, параметр подпрограммы, возвращаемое значение функции связывается с типом в момент объявления и тип не может быть изменён позже. Переменная или параметр будут принимать, а функция возвращать значения только этого типа.
Динамическая типизация – при которой переменная связывается с типом в момент присваивания значения, а не в момент объявления переменной. Таким образом, в различных участках программы одна и та же переменная может принимать значения разных типов.