Компилятор выполняет. Компиляция в программировании. Просто, но сложно

Современные компьютерные технологии находятся в постоянной стадии совершенствования. С каждым днем выходят все новые и новые технологии, позволяющие воплотить в жизнь то, что еще недавно определялось как фантастика. Сильным изменениям поддаются и языки, как человеческие, так и компьютерные. В данной статье мы подробно расскажем, что это – компилятор, как с ним работать, для чего он создавался и где его сейчас можно встретить. Статья рекомендуется не только начинающим пользователям операционной системы Windows, но и программистам, желающим познать скрытые знания своей системы.

Язык для операционной системы

Для начала стоит абстрагироваться, ведь программирование – это не только вбивание определенных ключей-слов в машину, это еще и тщательно продуманные действия, связанные с компонентами системы. Изначально был двоичный код, потом программисты создали полумашинный язык программирования – ассемблер, но для чего?

Представьте себе, что вам надо считать на калькуляторе программиста каждый бит, потом правильно его связывать и многое другое. В ассемблере все стало чуточку проще, но все еще очень и очень непросто, если сравнивать с современными языками программирования, например, С++, который называют одним из сложнейших, но про него речь пойдет чуть позже.

В языке ассемблер все осуществляется благодаря регистрам процессора: деление, умножение, перемещение значения из точки А в точку Б и т. д. Основная его проблема, что он все еще является полумашинным, но все равно поддается прочтению человеку, в отличии от хаотично раскиданных битов. Еще одним минусом было ограниченное количество этих самых регистров.

В 80-х годах решили придумать язык программирования, благодаря которому можно будет легко и просто написать операционную систему. Так появился С и компилятор С GCC от компании GNU. Если вы пользуетесь Linux, то обязательно должны были видеть продукты данной компании. Кстати, ассемблер используется и поныне, ведь некоторые компиляторы создают объектные файлы с двоичным кодом, а другие исполнительные – с кодом на ассемблере. Все зависит от платформы разработчика.

Современный компилятор имеет следующие программы в себе:

    Дебагер – программа, которая отправляет сообщения об ошибке от линковщика, препроцессора, интерпретатора. Препроцессор – это программа, главной задачей которой является поиск специальных меток, начинающихся со знака #, и выполнение определенного рода команд. Например, добавления сторонней библиотеки для компиляции проекта. Интерпретатор – программа, которая переводит наш более-менее понятный язык программирования в двоичный код или ассемблер. Линковщик – программа, благодаря которой недостающие файлы автоматически подключаются.

Также существует 2 типа сборки проекта компилятором: динамическая и статическая. В первой добавляются лишь нужные проекту файлы, несмотря на среду разработки, а во втором случае - все в кучу (подключенные, конечно). Итак, из этого уже можно сказать, что компилятор – это целый список программ для сбора и обработки информации в понятный и логичный для компьютера вид. Дальше мы рассмотрим, с чего все начиналось.

Первые простейшие компиляторы

Может, вы удивитесь, но впервые объект нашей статьи (тогда его еще называли транслятор) появился в далеком 1954 году в Институте, специализирующемся на прикладной математике. Он включал в себя не настолько большой комплекс программ, как сейчас, но все равно был прорывом в науке на то время. Там не было дебагера, поэтому людям приходилось все делать буквально руками, причем используя при этом стандартную и дискретную математику, чтобы узнать, правильный ли результат получила электронно-вычислительная машина.


Возможна ли сборка без нового языка?

Если вы достаточно толковый программист, то вполне сможете выполнить эту задачу. Правда, для этого понадобится немало времени и сил. Кстати, раньше даже была профессия такая – программист-линковщик. Это только в новых языках программирования все автоматизировано, а раньше людям приходилось связывать куски кода Make файлами. Между прочим, некоторые проекты на Linux и сейчас можно собрать с помощью этих самых Make-файлов, нужно лишь указать их зависимости вручную.


После сбора кода линковщик отдавал работу уже компьютеру на обработку, где в итоге получал готовый бинарный код.

Как видите, компилятор – это не только программа, а еще и усилия множества людей. А они, как утверждал Генри Форд, пытаются автоматизировать каждый процесс.

Лучший компилятор Windows

Итак, многие из читателей знают, что существует множество мертвых языков, но еще больше живых, т. е. тех, которые хотя бы раз в год обновляют свою стандартную библиотеку. Как мы уже говорили, в 1980 году был создан С - это был прорыв. Многие наши отцы до сих пор обожают данный язык, но что с ним теперь?

Он живет и процветает в новом теле, если так можно сказать. Его наследником по праву является С++, хоть и его создателя воспрещают писать на нем код, похожий на С, многие программисты игнорирует это и делают, но почему допускается такое грубое нарушение правил?


    Во-первых, он взял солидную долю стандартных библиотек от С, и новые компиляторы G++ способны компилировать код С, что уже само по себе указывает на их схожесть. Во-вторых, С++ был создан, чтоб заместить С, и итоги этого мы видим сейчас. К слову, программа компилятор G++ не "ругается" до тех пор, пока не будет использован хотя бы один класс – в этом и есть основное отличие двух языков. Можно назвать G++ лучшим компилятором, не зря ведь благодаря ему пишут мобильные приложения, операционную систему Windows и т. д.

Ваш путь будет тернист – это стоит знать прежде всего. Для начала работы с языком, например, если это С, вы обязательно должны будете ознакомиться с компилятором C. А если с ним не подружиться и не понять его логику, то ваши проекты один за одним будут лагать и вылетать.


Попытайтесь как можно больше читать книг не только про основы программирования, но и про историю создания языков, так вы обязательно начнете понимать саму суть процесса. Старайтесь совмещать практику и новые знания, так все куда быстрее запоминается. Кроме того, постарайтесь довести свой английский хотя бы до среднего уровня, иначе вам будет очень сложно в ориентировании по IDE.

В заключение

Надеемся, после прочтения данной статьи вы поняли, что это – компилятор, как он работает, зачем создавался и кому по сей день нужен. Стоит напомнить, что самое главное для программиста – это понимание ситуации, понимание основных принципов, поэтому очень надеемся, что статья вам в этом помогла.

ТРАНСЛЯЦИЯ, КОМПИЛЯЦИЯ И ИНТЕРПРЕТАЦИЯ

Транслятор – это программа или техническое средство, выполняющее преобразование программы, представленной на одном из языков программирования, в программу на другом языке, в определенном смысле равносильную первой.

Компиляция в программировании – преобразование программы, представленной на одном из языков программирования, в коды на машинно-ориентированном языке, которые принимаются и исполняются непосредственно процессором. Результатом компиляции является объектный файл с необходимыми внешними ссылками для компоновщика. Программа уже переведена в машинные инструкции, однако еще не полностью готова к выполнению.

Компилятор – это программа, предназначенная для трансляции исходного текста программы с высокоуровневого языка в объектный код. Входной информацией для компилятора является описание алгоритма или программа на языке программирования. На выходе компилятора – эквивалентное описание алгоритма на машинно-ориентированном языке (объектный код).

Компоновка – это один из этапов создания исполняемого файла.
Компилировать – проводить трансляцию машинной программы с проблемно-ориентированного языка на машинно-ориентированный язык (создание объектного кода) для ее исполнения. Результатом компиляции является объектный файл с необходимыми внешними ссылками для компоновщика. Программа уже переведена в машинные инструкции, однако еще не полностью готова к выполнению. В объектном файле имеются ссылки на различные системные функции. Даже если в программе явно не упомянута ни одна функция, необходим, по крайней мере, один вызов системной функции – завершение программы и освобождение всех принадлежащих ей ресурсов.

Компоновщик – модуль системы программирования или самостоятельная программа, которая собирает результирующую программу из объектных модулей и стандартных библиотечных модулей. Этот процесс называется компоновкой, его результатом и будет исполняемый файл. С процедурой интерпретации компоновка не связана.

При работе с программами существуют этапы:
а) компиляции
б) компоновки
в) интерпретации
г) исполнения программы.
Создание исполняемого файла из исходного текста программы предполагает выполнение этапов а и б (компиляции и компоновки).

Исполняемый файл – это файл, который может быть обработан или выполнен компьютером без предварительной трансляции. Обычно исполняемый файл получается в результате компиляции и компоновки объектных модулей и содержит машинные команды и/или команды операционной системы.

Интерпретатор анализирует и тут же выполняет программу покомандно, по мере поступления ее исходного кода на вход интерпретатора.
Алгоритм работы простого интерпретатора: 1) прочитать инструкцию;
2) проанализировать инструкцию и определить соответствующие действия;
3) выполнить соответствующие действия;
4) если не достигнуто условие завершения программы, прочитать следующую инструкцию и перейти к пункту 2.

Утверждение «Языковый процессор, который построчно анализирует исходную программу и одновременно выполняет предписанные действия, а не формирует на машинном языке скомпилированную программу, которая выполняется впоследствии» справедливо для интерпретатора

Режим интерпретации можно использовать при отладке программ на языке высокого уровня.

Интерпретация в разработке программ – процесс непосредственного покомандного выполнения программы без предварительной компиляции, «на лету». В большинстве случаев интерпретируемая программа работает намного медленнее, чем скомпилированная программа, но не требует затрат на компиляцию, что в случае небольших программ может повышать общую производительность. Интерпретация связана с получением переменными значений в процессе работы программы.

Интерпретация и компиляция не позволяют изменить семантику (смысл) языка программирования. Обычно при описании семантики в рамках операционного подхода исполнение конструкций языка программирования трактуется с помощью некоторой воображаемой (абстрактной) ЭВМ.

Интерпретация и компиляция не позволяют изменить синтаксис языка – набор правил построения фраз алгоритмического языка, позволяющий определить осмысленные предложения в этом языке.

Синтаксический анализ – это процесс сопоставления линейной последовательности лексем (слов) языка с его формальной грамматикой, обычно это программа или часть программы, выполняющая синтаксический анализ. Результатом обычно является дерево разбора.

Дисплейный файл – набор команд дисплейного процессора (представление интерактивной графики). В составе команд дисплейного процессора могут предусматриваться не только графические команды формирования изображений и перехода, но и команды организации циклов и обращения к подпрограммам.

Командные файлы используются, когда в процессе работы необходимо часто выполнять одни и те же действия. Операционная система позволяет записать нужную для этого последовательность команд в специальный файл, называемый командным файлом.

Этапы решения задачи на компьютере.

Для того чтобы правильно решить задачу с помощью автоматизированного подхода на ПЭВМ, необходимо пройти определенные этапы ее решения.
1. Формализация данных

2. Создание математической модели
3. Детальное описание алгоритма (блок-схема, текстовое)
4. Реализация на языке программирования
5. Отладка программы
6. Тестирование программы
7. Анализ результатов работы

Данная цепочка будет корректна с точки зрения решения задачи на ПЭВМ, поскольку на начальных этапах («Формализация данных» и «Создание математической модели») определяются исходные данные и модель решения. Далее, на этапах «Детальное описание алгоритма (блок-схема, текстовое)» и «Реализация на языке программирования», проходит пошаговое построение целевого алгоритма и реализация его на заданном языке программирования. На этапе «Отладка программы» устраняются явные некорректные ситуации реализации алгоритма, а этап «Тестирование программы» позволяет устранить скрытые и явные недостатки реализации исходной задачи. На финальном этапе «Анализ результатов работы» проводится исследование полученных результатов.

ПОНЯТИЕ АЛГОРИТМА И ЕГО СВОЙСТВА. БЛОК-СХЕМА АЛГОРИТМА

Единого определения понятия «алгоритм» нет. Приведем одно из возможных определений.

Алгоритм – это некоторый конечный набор рассчитанных на определенного исполнителя операций, в результате выполнения которых через определенное число шагов может быть достигнута поставленная цель или решена некоторая задача.

Пять важных свойств алгоритма – дискретность, конечность, детерминированность, результативность, массовость.

Дискретность – при выполнении алгоритм разбивается на конечную последовательность действий или шагов.

Конечность (завершаемость) – при корректно заданных исходных данных алгоритм должен завершать работу за конечное число шагов.

Детерминированность – это определенность (т. е. общепонятность и точность). В каждый момент времени следующий шаг работы однозначно определяется состоянием системы. Таким образом, алгоритм выдает один и тот же результат (ответ) для одних и тех же исходных данных, т. е. при повторениях алгоритма для одних и тех же исходных данных всегда получается одинаковый результат.

С другой стороны, существуют вероятностные алгоритмы, в которых следующий шаг работы зависит от текущего состояния системы и генерируемого случайного числа. Однако при включении метода генерации случайных чисел в список «исходных данных» вероятностный алгоритм становится подвидом обычного.

Результативность (направленность на получение искомого результата) ­– алгоритм должен завершаться определенными результатами.

Массовость (возможность использования различных данных при решении однотипных задач) – алгоритм должен быть применим к разным наборам исходных данных. Например, алгоритм решения квадратного уравнения должен быть применим к квадратным уравнениям с различными значениями коэффициентов.

Линейный алгоритм – алгоритм, в котором все действия (операции) выполняются один раз последовательно друг за другом

Способы записи (представления) алгоритма:

– формульный

– словесный

– табличный

– с помощью блок-схем

– с помощью программы

Наиболее наглядным способом записи алгоритма является изображение в виде последовательно блоков, каждый из которых предписывает выполнение определенных действий, то есть с помощью блок-схемы.

Способы представления алгоритмов (еще раз):

– Словесный (описание на естественном человеческом языке)

– Графический (на языке блок-схем)

– С помощью символов специального языка проектирования программ-псевдокодов

– С использованием HIPO-диаграмм

– С использованием таблиц решений

– С помощью схемы Насси-Шнейдермана

– С помощью одного из алгоритмических языков программирования

Правила построения алгоритмов на языке блок-схем:

1. Блок-схема строится сверху вниз.

2. В любой блок-схеме имеется только один элемент, соответствующий началу алгоритма, и один элемент, соответствующий концу алгоритма.

3. Должен быть хотя бы один путь из начала блок-схемы к любому элементу.

4. Должен быть хотя бы один путь от каждого элемента блок-схемы в конец блок-схемы.

Основные методы современной технологии проектирования алгоритмов.

1. Метод структурного проектирования. Любой алгоритм может быть построен из комбинаций трех базовых структур: линейный алгоритм (следование), разветвляющийся алгоритм (развилка) и циклический алгоритм (повтор).

2. Метод нисходящего проектирования. Первоначально определяются главные функции, затем второстепенные.

3. Метод пошаговой детализации.

4. Метод модульности. Модуль – логически связанный фрагмент программы, выполняющий одну функцию и состоящий из обозримого числа шагов.

Перед началом составления блок-схемы необходимо:

1. Определить имена входных данных, промежуточных и выходных результатов.

2. Дать наименование основной программе и вспомогательным алгоритмам.

Циклы . Оператор цикла. Заголовок цикла определяет число повторений. Тело цикла – блок повторяемых операторов (действий). Циклы бывают двух видов: с фиксированным числом повторений (цикл типа for = цикл типа для = цикл с параметром = арифметический цикл) и условные операторы цикла (цикл с предусловием = цикл типа while = цикл типа пока ; цикл с постусловием ).

Зацикливание – тело цикла выполняется бесконечное число раз.

Реализация циклов в алгоритмах уменьшает объем памяти, используемой программой, выполняющей алгоритм, и сокращает количество записей одинаковых последовательностей команд.

ЭВОЛЮЦИЯ И КЛАССИФИКАЦИЯ ЯЗЫКОВ ПРОГРАММИРОВАНИЯ. ОСНОВНЫЕ ПОНЯТИЯ ЯЗЫКОВ...

Выражение на языке программирования задает правило вычисления некоторого значения. Выражение состоит из констант, переменных, указателей функций, знаков операций и скобок. Каждое выражение имеет тип , зависящий от типов входящих в него операндов.

Выражение называют арифметическим , если его значением является число. Арифметическое выражениезаписывается в строку. Нельзя ставить подряд два знака арифметических операций. Нельзя опускать знак умножения.

При вычислении значений выражений важен порядок выполнения операций . Приняты следующие правила. Действия выполняются слева направо с соблюдением следующего старшинства (в порядке убывания приоритетов ):

1) действия в скобках;
2) вычисление функций;
3) NOT;
4) *, /, DIV, MOD, AND;
5) +, -, OR;
6) =, <>, <, >, <=, >=.

Если приоритет операций одинаков, то операция, стоящая левее, выполняется раньше . Порядок выполнения операций можно переопределить с помощью скобок.

Язык программирования – искусственный язык, который имеет

– ограниченное число слов, значение которых понятно транслятору

(ключевые слова)

– очень строгие правила записи команд

Синтаксис языка – совокупность правил записи команд

Семантика языка – смысл каждой команды и других конструкций языка

Язык программирования - формальная знаковая система, предназначенная для записи компьютерных программ. Язык программирования определяет набор лексических , синтаксических и семантических правил , задающих внешний вид программы и действия, которые выполнит исполнитель (компьютер) под ее управлением.

Каждый язык программирования поддерживает один или несколько встроенных типов данных (базовых типов). Кроме того, развитые языки программирования предоставляют программисту возможность описывать собственные типы данных, комбинируя или расширяя существующие.

Тип данных – характеристика набора данных, которая определяет:
- диапазон возможных значений данных из набора;
- допустимые операции, которые можно выполнять над этими значениями;
- способ хранения этих значений в памяти.
Различают:
- простые типы данных: целые, действительные числа и др.;
- составные типы данных: массивы, файлы и др.

Переменная – именованная область памяти, хранящая некоторое значение.

Массивы используются во всех современных языках программирования.

Массив – именованный набор однотипных данных, расположенных в памяти непосредственно друг за другом (в отличие от списка ), доступ к которым осуществляется по индексу элемента массива (номеру по порядку, упорядоченному по возрастанию в индексных массивах). Индекс массива, указывающий на элемент массива, – это целое число.

Программа – логически упорядоченная последовательность команд, необходимых для решения определенной задачи.

Программа – Алгоритм, записанный на языке программирования.

Текст программы – полное, законченное и детальное описание алгоритма на языке программирования. Затем этот текст программы обрабатывается специальными служебными приложениями, которые называются трансляторами.

Команды, поступающие в процессор по его шинам, на самом деле являются электрическими сигналами. Эти сигналы можно интерпретировать как нули и единицы, то есть как числа. Поэтому реально программа, с которой работает процессор, представляет собой последовательность чисел, называемую машинным кодом .

тестирование программного обеспечения - процесс исследования программного обеспечения (ПО) с целью получения информации о качестве продукта (в том числе поиск ошибок в программе).

Альфа-тестирование – тестирование готового продукта на специально созданных задачах.

Бета-тестирование – опробование бесплатной тестовой версии программного продукта на реальных задачах.

Если «альфа-» и «бета-тестирование» относятся к стадиям до выпуска продукта (а также, неявно, к объёму тестирующего сообщества и ограничениям на методы тестирования), тестирование «белого ящика» и «чёрного ящика» имеет отношение к способам, которыми тестировщик достигает цели .

При тестировании белого ящика (англ. white- box testing , также говорят - прозрачного ящика ), разработчик теста имеет доступ к исходному коду программ и может писать код, который связан с библиотеками тестируемого ПО. Это типично для юнит-тестирования (англ. unit testing ), при котором тестируются только отдельные части системы. Оно обеспечивает то, что компоненты конструкции - работоспособны и устойчивы, до определённой степени. При тестировании белого ящика используются метрики покрытия кода.

При тестировании чёрного ящика , тестировщик имеет доступ к ПО только через те же интерфейсы, что и заказчик или пользователь, либо через внешние интерфейсы, позволяющие другому компьютеру либо другому процессу подключиться к системе для тестирования. Например, тестирующий модуль может виртуально нажимать клавиши или кнопки мыши в тестируемой программе с помощью механизма взаимодействия процессов, с уверенностью в том, все ли идёт правильно, что эти события вызывают тот же отклик, что и реальные нажатия клавиш и кнопок мыши. Как правило, тестирование чёрного ящика ведётся с использованием спецификаций или иных документов, описывающих требования к системе. Как правило, в данном виде тестирования критерий покрытия складывается из покрытия структуры входных данных, покрытия требований и покрытия модели (в тестировании на основе моделей).

Регрессионное тестирование . После внесения изменений в очередную версию программы, регрессионные тесты подтверждают, что сделанные изменения не повлияли на работоспособность остальной функциональности приложения. Регрессионное тестирование может выполняться как вручную, так и средствами автоматизации тестирования.

Отла́дка - этап разработки компьютерной программы, на котором обнаруживают, локализуют и устраняют ошибки. Чтобы понять, где возникла ошибка, приходится:

    узнавать текущие значения переменных; и выяснять, по какому пути выполнялась программа.

Существуют две взаимодополняющие технологии отладки .

    Использование отладчиков - программ, которые включают в себя пользовательский интерфейс для пошагового выполнения программы: оператор за оператором, функция за функцией, с остановками на некоторых строках исходного кода или при достижении определённого условия. Вывод текущего состояния программы с помощью расположенных в критических точках программы операторов вывода - на экран, принтер, громкоговоритель или в файл. Вывод отладочных сведений в файл называется журналированием .

Отладчик – программа, позволяющая исследовать внутреннее устройство программы. Отладчик обеспечивает пошаговое исполнение программы, просмотр текущих значений переменных, вычисление значения любого выражения программы и др. Debugger .

Рефакторинг - процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы

Подпрограмма – набор операторов, выполняющих нужное действие и не зависящих от других частей исходного кода.

Подпрограммы бывают двух видов процедуры и функции . Они отличаются тем, что процедура просто выполняет группу операторов, а функция к тому же передает в главную программу некоторое вычисленное значение. Передает = возвращает. Функция имеет тип, совпадающий с типом возвращаемого значения.

Внешняя программа вызывает подпрограмму. Данные передаются подпрограмме в виде параметров или аргументов, которые описываются в заголовке подпрограммы.

Подпрограммы могут быть вложенными, т. е. допускается вызов подпрограммы не только из главной программы, но и из другой подпрограммы. Подпрограмма может вызывать сама себя. Такой прием называется рекурсией .

Важная характеристика подпрограмм – возможность их повторного использования. С интегрированными системами программирования поставляются большие библиотеки стандартных подпрограмм.

Модуль – процедура, функция, юнит, программа в целом – логически законченная составная часть программы.

Процедурные языки программирования – те, где возможно использование подпрограмм.

Структурное программирование – структура программы должна отражать структуру решаемой задачи, чтобы алгоритм решения был ясно виден из исходного текста. С этой целью введено понятие подпрограммы.

Структурное программирование - методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. Предложена в 70-х годах XX века Э. Дейкстрой, разработана и дополнена Н. Виртом.

В соответствии с данной методологией

Любая программа представляет собой структуру, построенную из трёх типов базовых конструкций:
    последовательное исполнение - однократное выполнение операций в том порядке, в котором они записаны в тексте программы; ветвление - однократное выполнение одной из двух или более операций, в зависимости от выполнения некоторого заданного условия; цикл - многократное исполнение одной и той же операции до тех пор, пока выполняется некоторое заданное условие (условие продолжения цикла).

В программе базовые конструкции могут быть вложены друг в друга произвольным образом, но никаких других средств управления последовательностью выполнения операций не предусматривается.

Повторяющиеся фрагменты программы (либо не повторяющиеся, но представляющие собой логически целостные вычислительные блоки) могут оформляться в виде т. н. подпрограмм (процедур или функций). В этом случае в тексте основной программы, вместо помещённого в подпрограмму фрагмента, вставляется инструкция вызова подпрограммы. При выполнении такой инструкции выполняется вызванная подпрограмма, после чего исполнение программы продолжается с инструкции, следующей за командой вызова подпрограммы. Разработка программы ведётся пошагово, методом «сверху вниз».

Сначала пишется текст основной программы, в котором, вместо каждого связного логического фрагмента текста, вставляется вызов подпрограммы, которая будет выполнять этот фрагмент. Вместо настоящих, работающих подпрограмм, в программу вставляются «заглушки», которые ничего не делают. Полученная программа проверяется и отлаживается. После того, как программист убедится, что подпрограммы вызываются в правильной последовательности (то есть общая структура программы верна), подпрограммы-заглушки последовательно заменяются на реально работающие, причём разработка каждой подпрограммы ведётся тем же методом, что и основной программы. Разработка заканчивается тогда, когда не останется ни одной «затычки», которая не была бы удалена. Такая последовательность гарантирует, что на каждом этапе разработки программист одновременно имеет дело с обозримым и понятным ему множеством фрагментов, и может быть уверен, что общая структура всех более высоких уровней программы верна. При сопровождении и внесении изменений в программу выясняется, в какие именно процедуры нужно внести изменения, и они вносятся, не затрагивая части программы, непосредственно не связанные с ними. Это позволяет гарантировать, что при внесении изменений и исправлении ошибок не выйдет из строя какая-то часть программы, находящаяся в данный момент вне зоны внимания программиста.

Нисходящее проектирование – разработка приложения (программы) сверху вниз. Сначала выделяется несколько подпрограмм (модулей), решающих самые глобальные задачи (например, инициализация данных), потом каждый из этих модулей детализируется на более низком уровне, разбиваясь на небольшое число других подпрограмм и т. д.

Событийно-ориентированное программирование – главная часть программы представляет собой один бесконечный цикл, который опрашивает Windows, следя за тем, не появилось ли новое сообщение о событии. При обнаружении события вызывается подпрограмма, ответственная за обработку события. Цикл продолжается, пока не будет получено сообщение «завершить работу».

События могут быть

пользовательскими (возникают в результате действий пользователя)

системными (возникают в ОС, например, сообщение от таймера)

программными (генерируются программой, например, надо обработать ошибку)

Исключение – ситуация в программе или ОС, требующая немедленного реагирования, например, деление на 0.

Виды программирования

    Структурное Функциональное программирование Логическое программирование Автоматное программирование Процедурное программирование Объектно-ориентированное программирование Прототипное программирование Аспектно-ориентированное программирование Компонентно-ориентированное программирование

Логическое программирование - парадигма программирования, основанная на автоматическом доказательстве теорем, а также раздел дискретной математики, изучающий принципы логического вывода информации на основе заданных фактов и правил вывода. Логическое программирование основано на теории и аппарате математической логики с использованием математических принципов резолюций. (язык Пролог ).

Процедурное (императивное) программирование является отражением архитектуры традиционных ЭВМ, которая была предложена фон Нейманом в 1940-х годах. Теоретической моделью процедурного программирования служит алгоритмическая система под названием Машина Тьюринга.

Программа на процедурном языке программирования состоит из последовательности операторов (инструкций), задающих процедуру решения задачи. Основным является оператор присваивания, служащий для изменения содержимого областей памяти. Концепция памяти как хранилища значений, содержимое которого может обновляться операторами программы, является фундаментальной в императивном программировании.

Выполнение программы сводится к последовательному выполнению операторов с целью преобразования исходного состояния памяти, то есть значений исходных данных, в заключительное, то есть в результаты. Таким образом, с точки зрения программиста имеются программа и память, причем первая последовательно обновляет содержимое последней.

Процедурный язык программирования предоставляет возможность программисту определять каждый шаг в процессе решения задачи. Особенность таких языков программирования состоит в том, что задачи разбиваются на шаги и решаются шаг за шагом. Используя процедурный язык, программист определяет языковые конструкции для выполнения последовательности алгоритмических шагов.

Процедурные языки программирования

· Аda (язык общего назначения)

· Basic (версии начиная с Quick Basic до появления Visual Basic)

· Фортран

· Модула-2

Функциональное программирование объединяет разные подходы к определению процессов вычисления на основе достаточно строгих абстрактных понятий и методов символьной обработки данных. Программирование с использованием математического понятия функции вызывает некоторые трудности, поэтому функциональные языки, в той или иной степени предоставляют и императивные возможности, что ухудшает дизайн программы (например возможность безболезненных дальнейших изменений). Дополнительное отличие от императивных языков программирования заключается в декларативности описаний функций. Тексты программ на функциональных языках программирования описывают «как решить задачу», но не предписывают последовательность действий для решения. Первым, спроектированным функциональным языком стал Лисп.

Машинный язык – язык программирования для представления программ в форме, допускающей их непосредственную реализацию аппаратными средствами конкретной ЭВМ.

Языки низкого уровня – Ассемблер и Макроассемблер.

Язык разметки данных в компьютерной терминологии – набор символов или последовательностей, вставляемых в текст для передачи информации о его выводе или строении. Принадлежит классу компьютерных языков . Текстовый документ, написанный с использованием языка разметки, содержит не только сам текст (как последовательность слов и знаков препинания), но и дополнительную информацию о различных его участках, например, указание на заголовки, выделения, списки и т. д. В более сложных случаях язык разметки позволяет вставлять в документ интерактивные элементы и содержание других документов.

Языки разметки используются везде, где требуется вывод форматированного текста: в типографии (SGML, TeX, PostScript, PDF), пользовательских интерфейсах компьютеров (Microsoft Word, OpenOffice, troff), Всемирной Сети (HTML, XHTML, XML, WML, VML, PGML, SVG).

XML (Hypertext Markup Language – «язык разметки гипертекста») – это стандартный язык разметки документов во Всемирной паутине.

Java – язык объектно-ориентированного программирования, разработан корпорацией Sun Microsistems как межплатформенный, интерпретируемый, объектно-ориентированный язык программирования, используемый для создания приложений, работающих под управлением веб-браузера и характеризующихся высоким уровнем интерактивности.

Java . Объектно-ориентированный язык программирования. Главная особенность этого языка – компиляция не в машинный код, а в байт-код, где каждая команда занимает 1 байт и который может выполняться на любой машине с любой операционной системой, если там есть интерпретатор. Этот интерпретатор называется «виртуальная машина Java ». Программы на языке java можно переносить с машины на машину в виде исходного текста или в виде байт-кода. По популярности Java занимает второе место в мире после Basic.

Java script – язык программирования, который разработан на основе языка Java и используется в составе html страниц с целью увеличения функциональности сайта.

Основное отличие языка Java script от любого другого языка программирования в том, что java скрипты размещаются внутри html страницы и не могут существовать как отдельные программы, а функционируют только будучи запущенными в браузерах.

SQL (Structured Query Language) – язык структурированных запросов. Структурированный язык запросов основан на реляционной алгебре. Это язык манипулирования данными, позволяющий описывать условия поиска информации, не задавая для этого последовательность действий, нужных для получения ответа. SQL является стандартным средством доступа к серверу баз данных . Стандарт SQL содержит компоненты для определения, изменения, проверки и защиты данных.

Пролог (англ. Prolog ) - язык и система логического программирования, основанные на языке предикатов математической логики дизъюнктов Хорна, представляющей собой подмножество логики предикатов первого порядка. Основными понятиями в языке Пролог являются факты, правила логического вывода и запросы, позволяющие описывать базы знаний, процедуры логического вывода и принятия решений.

ADA – язык программирования для встраиваемых систем. Это универсальный язык программирования, предназначенный для создания сложных систем, характеризующийся высокой степенью независимости от операционных систем и обеспечивающий поддержку средств параллельной обработки данных в реальном времени.

Интегрированные системы программирования включают в себя

· текстовый редактор

· компилятор

· редактор связей

· библиотеки функций

· отладчик (пошаговое выполнение)

Визуальные среды быстрого проектирования:

· Basic; Microsoft Visual Basic

· Pascal; Borland Delphi

· C++; Microsoft Visual C++

· Java; Borland JBuilder

· C#; Microsoft Visual ? Borland C# Builder

Архитектура программных систем : автономное приложение (работает на одном компьютере); файл-серверная архитектура, клиент-серверная архитектура, многозвенная архитектура (распределение функций между серверами, соединенными последовательно = позвенно), распределенная (программа в виде набора компонентов, которые можно запускать на любых серверах, связанных в сеть).

Параллельные вычисления – одновременное выполнение независимых частей одной программы на различных процессорах.

С точки зрения ISO 9126, Качество (программных средств) можно определить как совокупную характеристику исследуемого ПО с учётом следующих составляющих:

    Надёжность Сопровождаем ость Практичность Эффективность Мобильность Функциональность

Объектно-ориентированное программирование

Объектно-ориентированный язык – язык программирования, поддерживающий понятие объектов, их свойств и методов обработки, а также поддерживающий наследование и полиморфизм.

Класс специальный тип данных, который содержит поля, методы и свойства.

Поля – инкапсулированные в классе данные

Свойства специальный механизм, регулирующий доступ к полям.

Методы – инкапсулированные в классе процедуры и функции.

В основе классов лежат 3 фундаментальных принципа , которые называются инкапсуляция, наследование и полиморфизм.

Инкапсуляция – объединение трех сущностей (полей, методов и свойств) в единое целое (т. е. в класс), что позволяет во многом изолировать класс от остальных частей программы, сделать его самодостаточным для решения конкретной задачи. Например, класс Tform содержит (инкапсулирует в себе) все необходимое для создания Windows-окна.

Наследование – возможность создания новых классов на основе имеющегося класса с наследованием всех его полей, методов и свойств и добавлением новых. Класс, не имеющий предшественника, называется базовым.

Объект – это экземпляр реализации класса.

Объект (по тренажеру) – это совокупность свойств (структур данных, характерных для этого объекта), методов их обработки (подпрограмм изменения свойств) и событий, на которые данный объект может реагировать и которые приводят, как правило, к изменению свойств объекта.

Класс , от которого произошло наследование, называется базовым (по тренажеру) или родительским .

Классы , которые произошли от базового, называются потомками, наследниками или производными классами . Производные классы наследуют свойства и методы от базового класса.

Если базовый класс имеет ряд свойств и методов по обработке списков данных, то все наследники базового класса наследуют эти свойства и методы, но в то же время они могут иметь новые свойства и методы обработки.

Абстрактный класс в объектно-ориентированном программировании – класс, экземпляры которого не создаются. Абстрактный класс не может иметь объектов, так как в нем не определены операции над объектами; объекты должны принадлежать конкретным подклассам абстрактного класса. Абстрактные классы используются для спецификации интерфейсов операций.

Основным – Понятие основного класса не существует .

В основе объектно-ориентированного подхода лежит понятие иерархии классов .

· В объектно-ориентированном программировании понятию объекта соответствует схема А.

· При создании программы было использовано три визуально разных объекта, основанных на разных классах. Все объекты позволяют обрабатывать списки данных (но в разных графических представлениях) и обладают различными свойствами. На рисунке также представлена иерархическая структура классов для этих объектов. Класс, выделенный красным цветом, для трех используемых классов будет являться базовым

Разработана модель программы на языке визуального программирования Visual Basic, которая генерирует случайные числа в соответствии с выбранным законом и определенными параметрами. В разработанном графическом интерфейсе приложения используется_____9 _____ визуальных объектов.

Всего используется 9 объектов:
· 2 объекта «Поле ввода»,
· 3 объекта «Надпись»,
· 1 объект «Выпадающий список»,
· 1 объект «Выбор»,
· 1 объект «Кнопка»,
· 1 объект «Форма».

Разработана программа обработки графических изображений с использованием объектно-ориентированного подхода. Список доступных процедур обработки приведен на рисунке, а также реализован обработчик событий, который обрабатывает только те события, которые заданы пользователем. Сколько будет изменено свойств объекта изображение, если выполнить обработку при таком выборе? 3

Из всех выбранных событий только процедуры «Изменить размер изображения», «Изменить контраст», «Изменить Яркость» изменяют свойства объекта изображение.

Создана программа с использованием средств объектно-ориентированного подхода. На форме размещено два объекта: «Кнопка» и «Поле Выбора». Обработчик события «Нажатие кнопки» запрограммирован таким образом, чтобы изменить визуальные свойства этих объектов. На рисунке представлены объекты и их размещение до и после выполнения заявленного события. Если считать, что пространственные координаты объектов – это также визуальные свойства, то у объектов «Кнопка» и «Поле Выбора» изменилось ___7 ____визуальных свойств.

У объекта «Поле Выбора» изменились свойства: «Горизонтальное положение» и «Вертикальное положение», а также «Надпись» и «Состояние выбора». У объекта «Кнопка» изменилось «Горизонтальное положение» и «Вертикальное положение», а также «Надпись».

Виды компиляторов

  • Векторизующий . Транслирует исходный код в машинный код компьютеров, оснащённых векторным процессором .
  • Гибкий . Сконструирован по модульному принципу, управляется таблицами и запрограммирован на языке высокого уровня или реализован с помощью компилятора компиляторов.
  • Диалоговый . См.: диалоговый транслятор.
  • Инкрементальный . Повторно транслирует фрагменты программы и дополнения к ней без перекомпиляции всей программы.
  • Интерпретирующий (пошаговый) . Последовательно выполняет независимую компиляцию каждого отдельного оператора (команды) исходной программы.
  • Компилятор компиляторов . Транслятор, воспринимающий формальное описание языка программирования и генерирующий компилятор для этого языка.
  • Отладочный . Устраняет отдельные виды синтаксических ошибок.
  • Резидентный . Постоянно находится в оперативной памяти и доступен для повторного использования многими задачами.
  • Самокомпилируемый . Написан на том же языке, с которого осуществляется трансляция.
  • Универсальный . Основан на формальном описании синтаксиса и семантики входного языка. Составными частями такого компилятора являются: ядро, синтаксический и семантический загрузчики.

Виды компиляции

  • Пакетная . Компиляция нескольких исходных модулей в одном пункте задания.
  • Построчная . То же, что и интерпретация .
  • Условная . Компиляция, при которой транслируемый текст зависит от условий, заданных в исходной программе директивами компилятора. Так, в зависимости от значения некоторой константы, можно включать или выключать трансляцию части текста программы.

Структура компилятора

Процесс компиляции состоит из следующих этапов:

  1. Лексический анализ . На этом этапе последовательность символов исходного файла преобразуется в последовательность лексем.
  2. Синтаксический (грамматический) анализ . Последовательность лексем преобразуется в дерево разбора.
  3. Семантический анализ. Дерево разбора обрабатывается с целью установления его семантики (смысла) - например, привязка идентификаторов к их декларациям, типам, проверка совместимости, определение типов выражений и т. д. Результат обычно называется «промежуточным представлением/кодом», и может быть дополненным деревом разбора, новым деревом, абстрактным набором команд или чем-то ещё, удобным для дальнейшей обработки.
  4. Оптимизация . Выполняется удаление излишних конструкций и упрощение кода с сохранением его смысла. Оптимизация может быть на разных уровнях и этапах - например, над промежуточным кодом или над конечным машинным кодом.
  5. Генерация кода . Из промежуточного представления порождается код на целевом языке.

В конкретных реализациях компиляторов эти этапы могут быть разделены или, наоборот, совмещены в том или ином виде.

Генерация кода

Генерация машинного кода

Большинство компиляторов переводит программу с некоторого высокоуровневого языка программирования в машинный код , который может быть непосредственно выполнен процессором . Как правило, этот код также ориентирован на исполнение в среде конкретной операционной системы , поскольку использует предоставляемые ею возможности (системные вызовы , библиотеки функций). Архитектура (набор программно-аппаратных средств), для которой производится компиляция, называется целевой машиной .

Результат компиляции - исполнимый модуль - обладает максимальной возможной производительностью, однако привязан к определённой операционной системе и процессору (и не будет работать на других).

Некоторые компиляторы переводят программу с языка высокого уровня не прямо в машинный код, а на язык ассемблера . Это делается для упрощения части компилятора, отвечающей за кодогенерацию, и повышения его переносимости (задача окончательной генерации кода и привязки его к требуемой целевой платформе перекладывается на ассемблер), либо для возможности контроля и исправления результата компиляции программистом.

Генерация байт-кода

Результатом работы компилятора может быть программа на специально созданном низкоуровневом языке , подлежащем интерпретации виртуальной машиной . Такой язык называется псевдокодом или байт-кодом . Как правило, он не является машинным кодом какого-либо компьютера и программы на нём могут исполняться на различных архитектурах, где имеется соответствующая виртуальная машина, но в некоторых случаях создаются аппаратные платформы, напрямую поддерживающие псевдокод какого-либо языка. Например, псевдокод языка Java называется байт-кодом Java и выполняется в Java Virtual Machine , для его прямого исполнения была создана спецификация процессора picoJava . Для платформы .NET Framework псевдокод называется Common Intermediate Language (CIL), а среда исполнения - Common Language Runtime (CLR).

Некоторые реализации интерпретируемых языков высокого уровня (например, Perl) используют байт-код для оптимизации исполнения: затратные этапы синтаксического анализа и преобразование текста программы в байт-код выполняются один раз при загрузке, затем соответствующий код может многократно использоваться без промежуточных этапов.

Динамическая компиляция

Из-за необходимости интерпретации байт-код выполняется значительно медленнее машинного кода сравнимой функциональности, однако он более переносим (не зависит от операционной системы и модели процессора). Чтобы ускорить выполнение байт-кода, используется динамическая компиляция , когда виртуальная машина транслирует псевдокод в машинный код непосредственно перед его первым исполнением (и в при повторных обращениях к коду исполняется уже скомпилированный вариант).

CIL-код также компилируется в код целевой машины JIT-компилятором, а библиотеки .NET Framework компилируются заранее.

Декомпиляция

Существуют программы, которые решают обратную задачу - перевод программы с низкоуровневого языка на высокоуровневый. Этот процесс называют декомпиляцией, а такие программы - декомпиляторами . Но поскольку компиляция - это процесс с потерями, точно восстановить исходный код, скажем, на C++, в общем случае невозможно. Более эффективно декомпилируются программы в байт-кодах - например, существует довольно надёжный декомпилятор для Flash . Разновидностью декомпилирования является дизассемблирование машинного кода в код на языке ассемблера, который почти всегда выполняется успешно (при этом сложность может представлять самомодифицирующийся код или код, в котором собственно код и данные не разделены). Связано это с тем, что между кодами машинных команд и командами ассемблера имеется практически взаимно-однозначное соответствие.

Раздельная компиляция

Раздельная компиляция (англ. separate compilation ) - трансляция частей программы по отдельности с последующим объединением их компоновщиком в единый загрузочный модуль.

Исторически особенностью компилятора, отражённой в его названии (англ. compile - собирать вместе, составлять), являлось то, что он производил как трансляцию , так и компоновку, при этом компилятор мог порождать сразу абсолютный код. Однако позже, с ростом сложности и размера программ (и увеличением времени, затрачиваемого на перекомпиляцию), возникла необходимость разделять программы на части и выделять библиотеки , которые можно компилировать независимо друг от друга. При трансляции каждой части программы компилятор порождает объектный модуль , содержащий дополнительную информацию, которая потом, при компоновке частей в исполнимый модуль, используется для связывания и разрешения ссылок между частями.

Появление раздельной компиляции и выделение компоновки как отдельной стадии произошло значительно позже создания компиляторов. В связи с этим вместо термина «компилятор» иногда используют термин «транслятор» как его синоним: либо в старой литературе, либо когда хотят подчеркнуть его способность переводить программу в машинный код (и наоборот, используют термин «компилятор» для подчёркивания способности собирать из многих файлов один).

На заре развития компьютеров первые компиляторы (трансляторы) называли «программирующими программами» (так как в тот момент программой считался только машинный код, а «программирующая программа» была способна из человеческого текста сделать машинный код, то есть запрограммировать ЭВМ).

См. также

Примечания

Литература

  • Альфред В. Ахо, Моника С. Лам, Рави Сети, Джеффри Д. Ульман. Компиляторы: принципы, технологии и инструментарий = Compilers: Principles, Techniques, and Tools. - 2-е изд. - М .: Вильямс, 2010. - 1184 с. - ISBN 978-5-8459-1349-4
  • Робин Хантер. Основные концепции компиляторов = The Essence of Compilers. - М .: Вильямс, 2002. - 256 с. - ISBN 0-13-727835-7
  • Хантер Р. Проектирование и конструирование компиляторов / Пер. с англ. С. М. Круговой. - М .: Финансы и статистика, 1984. - 232 с.
  • Д. Креншоу. Давайте создадим компилятор!
  • Серебряков В. А., Галочкин М. П. Основы конструирования компиляторов .

Wikimedia Foundation . 2010 .

Синонимы :

Смотреть что такое "Компилятор" в других словарях:

    - (ново лат., от лат. compilare грабить, обирать, выбирать). Составитель статей или книг путем заимствования отрывков из сочинений разных авторов. Словарь иностранных слов, вошедших в состав русского языка. Чудинов А.Н., 1910. КОМПИЛЯТОР… … Словарь иностранных слов русского языка

    См. писатель... Словарь русских синонимов и сходных по смыслу выражений. под. ред. Н. Абрамова, М.: Русские словари, 1999. компилятор автор, писатель; транслятор, халтурщик, программа Словарь русских синонимов … Словарь синонимов

    Программа, преобразующая текст, написанный на алгоритмическом языке, в программу, состоящую из машинных команд. Компилятор создает законченный вариант программы на машинном языке. См. также: Трансляторы Финансовый словарь Финам … Финансовый словарь

    КОМПИЛЯТОР, КОМПЬЮТЕРНАЯ ПРОГРАММА, которая переводит символы ЯЗЫКА ПРОГРАММИРОВАНИЯ в команды, которые может непосредственно воспринимать компьютер. Программы по большей части пишутся на ЯЗЫКАХ ВЫСОКОГО УРОВНЯ, таких как «Си», Паскаль или Бейсик … Научно-технический энциклопедический словарь

    КОМПИЛЯТОР, компилятора, муж. (книжн.). Автор компиляции. || Литератор, способный писать только компиляции (пренебр.). Жалкий компилятор. Толковый словарь Ушакова. Д.Н. Ушаков. 1935 1940 … Толковый словарь Ушакова

Когда программисты разговаривают о программировании, они часто говорят: «программа откомпилировалась без ошибок», или, когда говорят программисту: «скомпилируй программу, посмотрим на результат работы». Такие разговорчики позднее могут стать источником путаницы для . Компиляция и создание исполняемого файла — не синонимы! Создание исполняемых файлов — это многоступенчатый процесс, основные составляющие которого: компиляция и компоновка. На самом деле, даже если программа «откомпилировалась без ошибок», она может не работать из-за возможной ошибки во время стадии компоновки. Весь процесс трансляции файлов исходного кода в исполняемый файл лучше было бы называть построением проекта.

Компиляция!

Компиляция относится к обработке файлов исходного кода (.c, .cc, или.cpp) и создании объектных файлов проекта. На этом этапе не создается исполняемый файл. Вместо этого компилятор просто транслирует высокоуровневый код в машинный язык. Например, если вы создали (но не скомпоновали) три отдельных файла, у вас будет три объектных файла, созданные в качестве выходных данных на этапе компиляции. Расширение таких файлов будет зависеть от вашего компилятора, например *.obj или *.o. Каждый из этих файлов содержит машинные инструкции, которые эквивалентны исходному коду. Но вы не можете запустить эти файлы! Вы должны превратить их в исполняемые файлы операционной системы, только после этого их можно использовать. Вот тут за дело берётся компоновщик.

Компоновка!

Из нескольких объектных файлов создается единый исполняемый файл. На этом этапе полученный файл является единственным, а потому компоновщик будет жаловаться на найденные неопределенные функции. На этапе компиляции, если компилятор не мог найти определение для какой-то функции, считается, что функция была определена в другом файле. Если это не так, компилятор об этом знать не будет, так как не смотрит на содержание более чем одного файла за раз. Компоновщик, с другой стороны, может смотреть на несколько файлов и попытаться найти ссылки на функции, которые не были упомянуты.

Вы спросите, почему этапы компиляции и компоновки разделены. Во-первых, таким образом легче реализовать процесс построения программ. Компилятор делает свое дело, а компоновщик делает свое дело — посредством разделения функций, сложность программы

снижается. Другим (более очевидным) преимуществом является то, что это позволяет создавать большие программы без необходимости повторения шага компиляции каждый раз, когда некоторые файлы будут изменены. Вместо этого, используется так называемая «условная компиляция». То есть объекты составляются только для тех исходных файлов, которые были изменены, для остальных, объектные файлы не пересоздаются. Тот факт, что каждый файл компилируется отдельно от информации, содержащейся в других файлах,

существует благодаря разделению процесса построения проекта на этапы компиляции и компоновки.

Эти два этапа берёт на себя и вам не стоит беспокоиться о том, какие из файлов были изменены. IDE сама решает,когда создавать объекты файлов, а когда нет.

Зная разницу между фазами компиляции и компоновки вам будет намного проще находить ошибки в своих проектах. Компилятор отлавливает, как правило, — отсутствие точки с запятой или скобок. Если вы получаете сообщение об ошибке, множественного определения функции или переменной, знайте, вам об этом сообщает компоновщик. Эта ошибка может означать только одно, что в нескольких файлах проекта определены одна и та же функция или переменная.

Одной из ключевых характеристик PHP является то, что это интерпретируемый язык программирования. С другой стороны, языки программирования наподобие C , изначально разрабатывались для компиляции. Что это значит?

Компилируется ли язык программирования или интерпретируется, на самом деле это не зависит от природы языка программирования. Любой язык программирования может интерпретироваться так называемым интерпретатором или компилироваться с помощью так называемого компилятора.

Рабочий цикл программы

При использовании любого языка программирования существует определенный рабочий цикл создания кода. Вы пишете его, запускаете, находите ошибки и отлаживаете. Таким образом, вы переписываете и дописываете программу, проверяете ее. То, о чем пойдет речь в этой статье, это «запускаемая » часть программы.

Когда пишете программу, вы хотите, чтобы ее инструкции работали на компьютере. Компьютер обрабатывает информацию с помощью процессора, который поэтапно выполняет инструкции, закодированные в двоичном формате. Как из выражения «a = 3; » получить закодированные инструкции, которые процессор может понять?

Мы делаем это с помощью компиляции. Существует специальные приложения, известные как компиляторы. Они принимают программу, которую вы написали. Затем анализируют и разбирают каждую часть программы и строят машинный код для процессора. Часто его также называют объектным кодом.

На одном из этапов процесса обработки задействуется компоновщик, принимающий части программы, которые отдельно были преобразованы в объектный код, и связывает их в один исполняемый файл. Вот схема, описывающая данный процесс:

Конечным элементом этого процесса является исполняемый файл. Когда вы запускаете или сообщаете компьютеру, что это исполняемый файл, он берет первую же инструкцию из него, не фильтрует, не преобразует, а сразу запускает программу и выполняет ее без какого-либо дополнительного преобразования. Это ключевая характеристика процесса компиляции — его результат должен быть исполняемым файлом, не требующим дополнительного перевода, чтобы процессор мог начать выполнять первую инструкцию и все следующие за ней.

Первые компиляторы были написаны непосредственно через машинный код или с использованием ассемблеров. Но цель компилятора очевидна: перевести программу в исполняемый машинный код для конкретного процессора.

Некоторые языки программирования разрабатывались с учетом компиляции. C , например, предназначался для того, чтобы дать возможность программистам с легкостью реализовать разные вещи. Но в итоге он разрабатывался таким образом, чтобы его можно было легко перевести на машинный код. Компиляция в программировании это серьезно!

Не все языки программирования учитывают это в своей концепции. Например, Java предназначался для запуска в «интерпретирующей » среде, а Python всегда должен интерпретироваться.

Интерпретация программы

Альтернативой компиляции является интерпретация. Основная разница между компилятором и интерпретатором заключается в том, как они работают. Компилятор берет всю программу и преобразует ее в машинный код, который понимает процессор.

Интерпретатор — это исполняемый файл, который поэтапно читает программу, а затем обрабатывает, сразу выполняя ее инструкции.

Другими словами, интерпретатор выполняет программу поэтапно как часть собственного исполняемого файла. Объектный код не передается процессору, интерпретатор сам является объектным кодом, построенным таким образом, чтобы его можно было вызвать в определенное время.

Это ломает рабочий цикл, который был приведен на диаграмме выше. Теперь у нас есть новая диаграмма:


На ней мы видим, что в отличие от компилятора, интерпретатор всегда должен быть под рукой, чтобы мы могли вызвать его и запустить нашу программу. В некотором смысле интерпретатор становится процессором. Программы, написанные для интерпретации, называются «скриптами », потому что они являются сценариями действий для другой программы, а не прямым машинным кодом.

Например, так работают такие языки программирования, как Python . Вы пишете программу. Затем вводите код в интерпретатор Python , и он выполняет все описанные вами шаги. В командной строке вы можете ввести примерно следующее:

C:>python myprogram.py

В этой команде Python — это исполняемый файл. Вы вводите в него все, что находится в файле myprogram.py, и он выполняет эти инструкции. Компьютер не запустит myprogram.py без Python . Это не машинный код, который понимает процессор. Можно скомпилировать программы Python в объектный или машинный код и запустить его непосредственно в процессоре. Но эта процедура включает в себя компиляцию кода и добавление в качестве ее части всего интерпретатора Python .

Природа интерпретатора

Интерпретаторы могут создаваться по-разному. Существуют интерпретаторы, которые читают исходную программу и не выполняют дополнительной обработки. Они просто берут определенное количество строк кода за раз и выполняют его.

Некоторые интерпретаторы выполняют собственную компиляцию, но обычно преобразуют программу байтовый код, который имеет смысл только для интерпретатора. Это своего рода псевдо машинный язык, который понимает только интерпретатор.

Такой код быстрее обрабатывается, и его проще написать для исполнителя (части интерпретатора, которая исполняет ), который считывает байтовый код, а не код источника.

Есть интерпретаторы, для которых этот вид байтового кода имеет более важное значение. Например, язык программирования Java «запускается » на так называемой виртуальной машине. Она является исполняемым кодом или частью программы, которая считывает конкретный байтовый код и эмулирует работу процессора. Обрабатывая байтовый код так, как если бы процессор компьютера был виртуальным процессором.

У меня есть эмулятор для игровой приставки NIntendo . Когда я загружаю ROM-файл Dragon Warrior , он форматируется в машинный код, который понимает только процессор NES . Но если я создаю виртуальный процессор, который интерпретирует байтовый код во время работы на другом процессоре, я могу запустить Dragon Warrior на любой машине с эмулятором.

Это использует концепция компиляции Java , а также все интерпретаторы. На любом процессоре, для которого я могу создать интерпретатор / эмулятор, можно запускать мои интерпретируемые программы / байтовый код. В этом заключается основное преимущество интерпретатора над компилятором.

За и против

Основным аргументом за использование процесса компиляции является скорость. Возможность компилировать любой программный код в машинный, который может понять процессор ПК, исключает использование промежуточного кода. Можно запускать программы без дополнительных шагов, тем самым увеличивая скорость обработки кода.

Но наибольшим недостатком компиляции является специфичность. Когда компилируете программу для работы на конкретном процессоре, вы создаете объектный код, который будет работать только на этом процессоре. Если хотите, чтобы программа запускалась на другой машине, вам придется перекомпилировать программу под этот процессор. А перекомпиляция может быть довольно сложной, если процессор имеет ограничения или особенности, не присущие первому. А также может вызывать ошибки компиляции.

Основное преимущество интерпретации — гибкость. Можно не только запускать интерпретируемую программу на любом процессоре или платформе, для которых интерпретатор был скомпилирован. Написанный интерпретатор может предложить дополнительную гибкость. В определенном смысле интерпретаторы проще понять и написать, чем компиляторы.

С помощью интерпретатора проще добавить дополнительные функции, реализовать такие элементы, как сборщики мусора, а не расширять язык.

Другим преимуществом интерпретаторов является то, что их проще переписать или перекомпилировать для новых платформ.

Написание компилятора для процессора требует добавления множества функций, или полной переработки. Но как только компилятор написан, можно скомпилировать кучу интерпретаторов и на выходе мы имеем перспективный язык. Не нужно повторно внедрять интерпретатор на базовом уровне для другого процессора.

Самым большим недостатком интерпретаторов является скорость. Для каждой программы выполняется так много переводов, фильтраций, что это приводит к замедлению работы и мешает выполнению программного кода.

Это проблема для конкретных real-time приложений, таких как игры с высоким разрешением и симуляцией. Некоторые интерпретаторы содержат компоненты, которые называются just-in-time компиляторами (JIT ). Они компилируют программу непосредственно перед ее исполнением. Это специальные программы, вынесенные за рамки интерпретатора. Но поскольку процессоры становятся все более мощными, данная проблема становится менее актуальной.

Заключение

Имейте всегда в виду, что некоторые языки программирования специально предназначены для компиляции кода, например, C . В то время как другие языки всегда должны интерпретироваться, например Java .

Для меня не имеет значения, скомпилировано что-то или интерпретировано, если оно может выполнить задачу эффективно.

Некоторые системы не предлагают технические условия для эффективного использования интерпретаторов. Поэтому вы должны запрограммировать их с помощью чего-то, что может быть непосредственно скомпилировано, например C . Иногда нужно выполнить вычисления настолько интенсивно, насколько это возможно. Например, при точном распознавании голоса роботом. В других случаях скорость или вычислительная мощность могут быть не столь критичными, и написать эмулятор на оригинальном языке может быть проще.




Top