Добавлен: 14.06.2023
Просмотров: 225
Скачиваний: 2
Современные языки программирования не ограничиваются какой-то одной парадигмой, а используют их несколько или являются мультипарадигмальными. Это связано со стремлением разработчиков языка расширить области их применения, и сделать его языком общего назначения, а не ориентированным на решение узкого круга задач.
Пользоваться почти всеми языками объектно-ориентированного подхода наряду с процедурным, обусловлено сложностью современных задач. Создание больших систем просто невозможно без создания структурной модели, а работа с объектами значительно облегчает разработку и отладку таких систем.
Глава 3. Трансляторы
Так как текст, который написан на языке программирования, непонятен компьютеру, то необходимо перевести на машинный код. Перевод программы с языка программирования на язык машинного кода называется трансляцией и выполняется специализированными программами – трансляторами.
Транслятор – это специальная обслуживающая программа, которая преобразовывает исходную программу, представленную на языке программирования, в рабочую программу, представленную на объектном языке.
На сегодняшний день трансляторы разделяют на две группы:
-
- компиляторы;
- интерпретаторы.
3.1. Компилятор
Компилятор – это специальная обслуживающая программа, выполняющая трансляцию на машинный код, записанный на исходном языке программирования.
Компилятор обеспечивает преобразование программы с одного языка на другой. Команды исходного языка отличаются по организации и мощности от команд машинного языка. Есть языки, в которых одна команда исходного языка транслируется в 7-10 машинных команд. В исходном языке часто используется строгая типизация данных, которая осуществляется через их предварительное описание. Процесс трансляции с таких языков обычно называется компиляцией, а исходные языки обычно относятся к высокоуровневым языкам.[6]
3.2. Интерпретатор
Интерпретатор – это устройство или программа, которая осуществляет пооператорную трансляцию и выполнение исходной программы.
Интерпретатор на выходе не порождает программу на машинном языке. Распознав команду исходного языка, он тут же выполняет ее.
Типы интерпретаторов:
- Простой интерпретатор – анализирует и тут же выполняет программу покомандно.
- Достоинством является мгновенная реакция;
- Недостаток – обнаруживает ошибки в тексте программы только при попытке выполнении команды с ошибкой.
- Интерпретатор компилирующего типа – система из компилятора, превосходящего исходный код программы в промежуточное направление.
- Достоинством является большее быстродействие выполнение программ;
- Недостаток – большее требование к ресурсам и требование на корректность исходного кода.[6]
Достоинства интерпретаторов:
- Переносимость интерпретируемых программ – программа будет работать на всех платформах, на которых есть соответствующий интерпретатор;
- Простая отладка исходных кодов программ – интерпретатор позволяет начать обработку данных после написания даже после одной команды;
- Небольшие размеры кода по сравнению с машинным кодом, полученным после обычных компиляторов.
Недостатки интерпретаторов:
- Программа не может выполняться отдельно при отсутствии программы-интерпретатора. При этом сам интерпретатор может быть не очень компактным;
- Интерпретируемая программа выполняется медленнее, поскольку промежуточный анализ исходного кода и его выполнения требуют дополнительного времени в сравнении с исполнением машинного кода, в который мог бы быть скомпилирован исходный код.
- Практически отсутствует оптимизация кода, что приводит к дополнительным потерям в скорости работы интерпретируемых программ.
Какие трансляторы применяются в современных языках программирования, представлены в таблице 3.
Таблица 3. Трансляторы современных языках программирования
|
Язык программирования |
Транслятор |
|
Java |
компиляция в байт-код интерпретатор |
|
С |
компилятор |
|
С++ |
компилятор |
|
Python |
компиляция в байт-код интерпретатор |
|
Visual Basic .Net |
компиляция в MSIL-код компилятор интерпретатор |
|
C# |
компиляция в MSIL-код интерпретатор |
|
PHP |
компиляция в байт-код интерпретатор |
|
JavaScript |
компиляция в байт-код интерпретатор |
|
Assembly language |
компилятор интерпретатор |
|
Perl |
компиляция в байт-код интерпретатор |
Современные языки программирования используют в равной степени компиляцию и интерпретацию.
Большее использование компиляторов связано с большой скоростью работы программ и создание машинно-зависимых участков кода и программ.
Использование интерпретации, позволяет оградить программиста от особенностей конкретных платформ, и очень востребовано в связи с развитием Интернет-технологий.
Среди всех интерпретируемых языком используются в основном интерпретаторы компилирующего типа, что обусловлено значительным увеличением скорости работы программ в сравнении с простыми интерпретаторами. При разработке большого и сложного программного обеспечения такое увеличение скорости может быть очень существенным.
Глава 4. Типизация данных
Тип – это устойчивая и независимая совокупность элементов, которую можно выделить во всём рассматриваемом множестве.
Математически тип может быть определен двумя способами:
-
- Множеством всех значений, принадлежащим типу;
- Предикатной функцией, определяющей принадлежность объекта к данному типу.
Тип данных – это понятие теории программирования. Он определяет множество значений, набор операций, которые можно применять к таким значениям, а так же способ реализации хранения значений и выполнение операций. Все данные, которыми оперируют программы, относятся к определенным типам данных.
Типы данных различаются так же и на нижних уровнях системы. Даже в Ассемблере x86 различают такие типы как «целое число» и «вещественное число». Это объясняется тем, что для чисел разных типов отводятся разные объемы памяти, используются различные регистры микропроцессора, и для операций над ними применяются разные команды Ассемблера и разные ядра микропроцессора.
В языках программирования типы данных не всегда соответствуют подобным математическим типам. Например, тип “целое число” большинства языков программирования не соответствует принятому в математике типу “целое число”, так как в математике указанный тип не имеет ограничений ни сверху, ни снизу, а в языках программирования эти ограничения есть. Как правило, в языках и системах имеется множество целых типов, отличающихся допустимым диапазоном значений (определяемым объёмом занимаемой памяти).
Часто используемые типы данных:
- Простые:
- Перечисляемый тип – хранит значения прямо указанные в его описании.
- Целочисленный тип – хранит целое число и без знака.
- Вещественный тип – хранит вещественное число с запятой и с плавающей точкой.
- Символьный тип – хранит один символ в разных кодировках.
- Множество – совпадает с обычным математическим понятием множества.
- Логический тип – принимает только два значения ложь(false)=0 и истина(true)=1.
- Указатель – хранит адрес в памяти, который указывает на какую-либо информацию, как правило – указатель на переменную.
- Составные:
- Массив – хранит индексированный набор элементов одного типа.
- Строковый тип – хранит строку набора символов.
- Запись или структура – хранит набор разных элементов или полей, который хранится как единое целое.
- Файловый тип – хранит только однотипные значения, к которым доступ осуществляется только последовательно.
- Класс, метакласс и интерфейс – хранит абстрактные типы данных в объектно-ориентированном программировании.
Типы переменных и параметров должны совпадать с присваиваемыми им значениями или вызываемыми для них функциями. Для совместимости типов переменных и их значений во всех языках программирования осуществляется контроль типов и называется типизацией. Типизация – это процесс проверки и накладывания ограничений использование типов.
Существует всего два вида контроля типов данных:
-
- Статистическая типизация, – при которой переменная, параметр подпрограммы, возвращаемое значение функции связывается с типом в момент объявления и тип не может быть изменён позже. Переменная или параметр будут принимать, а функция возвращать значения только этого типа.
- Динамическая типизация, - при которой переменная связывается с типом в момент присваивания значения, а не в момент объявления переменной. Таким образом, в различных участках программы одна и та же переменная может принимать значения разных типов.
Подходы для определения соответствия типов данных:
-
- Строгая типизация – совместимость типов автоматически контролируется транслятором, она должна быть явно наследована при определении типа или определятся структурой самого типа.
- Слабая типизация – совместимость типов транслятором не контролируется. В языках программирования со слабой типизацией обычно используется подход, который называется «утиная типизация» - это когда совместимость определяется и реализуется общим интерфейсом доступа к данным типа.
На сегодняшний день не существует единого мнения о том, какой вид типизации лучше.
4.1. Динамическая типизация данных
Так как переменная связывается с типом в момент присваивания и в ходе выполнения программы может менять свой тип, контролировать на этапе проектирования соответствие такой переменной вызываемым для нее функциям и методам невозможно. Поэтому транслятор встраивает в программу операции связанные с динамической проверкой типа.
Недостатки динамической типизации:
-
- Низкая скорость выполнения, которая связана с динамической проверкой типа переменной перед каждым использованием.
- Возникают ошибки, связанные с опечатками при использовании имени переменной.
- Масса возможностей для простых ошибок, для обнаружения которых необходимо, как минимум выполнить данный участок кода.
- В объектно-ориентированных языках программирования не действуют или действует с ограничениями автодополнение: невозможно или совсем трудно понять, к какому типу относится переменная, и вывести ее набор методов и полей.
Если учесть эти недостатки, то для написания сложного кода нужна особая культура программирования: венгерская нотация или юнит-тестирование. Кроме этого, в таких языках программирования отсутствует интерфейсная часть модуля, которая сама по себе является существенной частью документации, а иногда вообще позволяет обойтись и без документирования.
Отсутствие проверки типов данных на этапе написания и трансляции программы ведет к появлению некоторых достоинств:
- Ускоряется работа – а это значит, цикл «написать - проверить», что для больших проектов может быть существенным.
- Повышается гибкость языка – возможна реализация функций, вычисляющей значение выражения произвольного типа.
Отсутствуют дополнительные строки, связанные с определением типа данных и даже с объявлением переменных и операции приведения типа. Соответственно упрощается написания простых программ. В разных языках программирования динамический контроль типов реализован по-разному. Благодаря этому в некоторых языках недостатки данного вида типизации могут быть сведены к нулю, так же как и достоинства.
4.2. Статическая типизация данных
При этом виде контроля переменная связывается с типом в момент объявления еще при написании программы и проверяется на соответствие при каждом ее использовании программистом.
Недостатки:
-
- Понижается гибкость языка – для каждого типа переменной необходима реализация собственной функции.
- Значительно замедляется работа компилятора.
Достоинства:
-
- Высокая скорость выполнения программы, которая связана с отсутствием проверки типов на этапе выполнения. Зная тип переменной транслятор, может использовать для нее более простые команды.
- Уменьшается количество ошибок, которые связаны с некорректным использованием типа переменной, такие как присваивание значений, операции над переменными и передача параметров в функции.
- При явном объявлении переменных и типов повышается читабельность и понятность кода, а так же упрощается документирование программы.
Так же как и для динамического контроля, статический контроль типов данных в языках программирования реализован по-разному, что с учетом строгой или слабой типизации может налагать ряд дополнительных достоинств и недостатков.
Виды типизации в современных языках программирования представлены в таблице 4.