Переводит сразу всю программу в коды и создает независимый исполняемый exe-файл

Обновлено: 28.06.2024

Процесс преобразования исходного кода C++ в исполняемую программу называется "компиляция программы" или просто "компиляция". Мы обычно рассматриваем процесс компиляции как одно действие и обычно называем его таковым. Тем не менее, современный компилятор C++ состоит как минимум из трех отдельных программ:

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

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

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

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

Препроцессор

имя > Угловые скобки обозначают системный включаемый файл, который является частью самого компилятора (представьте его как «библиотечный» код) и указывает препроцессору искать файл везде, где расположены системные заголовочные файлы (что варьируется от одного компилятора в другой и из одной операционной системы в другую). " name.h " Двойные кавычки идентифицируют файл заголовка, который записывается как часть программы. Кавычки указывают препроцессору искать заголовочный файл в текущем каталоге (т. е. в том же каталоге, что и исходный код C++). Файлы заголовков, которые программист пишет как часть прикладной программы, обычно заканчиваются расширением .h.

В программе C++ вы можете увидеть два типа системных заголовочных файлов. Старые заголовочные файлы системы заканчиваются расширением «.h»: . Эти заголовочные файлы изначально создавались для программ на C, но могут использоваться и с C++. Более новые файлы системных заголовков не заканчиваются расширением: , могут использоваться только с C++.

Примеры директив. Имена файлов, находящиеся между и >, относятся к системным заголовочным файлам; имя файла, появляющееся между открытием и закрытием " относится к файлам заголовков, написанным программистом как часть программы.

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

  1. Программист пишет "NAME_SIZE" в исходном коде C++.
  2. Препроцессор заменяет символы NAME_SIZE символами 25
  3. Компонент компилятора "видит" и компилирует "25", а не NAME_SIZE

Символические/именованные/манифестные константы полезны двумя важными способами:

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

Компонент компилятора

Компонент компилятора, средняя программа в общей системе компилятора, является самой большой и, возможно, самой важной частью системы. Компилятор переводит исходный код C++ в машинный код, который конкретный компьютер «понимает» и может выполнять. На рисунке ниже показано, что одна программа может состоять из нескольких файлов с исходным кодом. Программы бывают самых разных размеров, от нескольких десятков строк кода до многих миллионов строк. Работать с большими программами в одном файле с исходным кодом и неудобно, и неудобно, а распределение их по нескольким файлам имеет много преимуществ:

  1. Он разбивает большие и сложные программы на более мелкие, независимые концептуальные единицы, которые легче понять и которым легче следовать.
  2. Он позволяет нескольким программистам работать над одной программой одновременно; каждый программист работает с отдельным набором файлов
  3. Это ускоряет компиляцию. Компонент компилятора сохраняет сгенерированный машинный код в объектном файле, по одному объектному файлу на каждый файл исходного кода. Система компилятора не удаляет объектные файлы, поэтому, если файл исходного кода не изменился, компоновщик использует существующий файл объектного кода.
  4. Это позволяет родственным программам обмениваться файлами. Например, офисные пакеты часто включают в себя текстовый процессор, редактор слайд-шоу и электронную таблицу.Сохраняя код пользовательского интерфейса в одном общем файле, они могут представить согласованный пользовательский интерфейс.
  5. Хотя это и менее важно, это позволяет разработчикам программного обеспечения продавать программное обеспечение как объектный код, организованный в виде библиотек, что полезно при предоставлении кода, взаимодействующего с такими приложениями, как система управления базами данных.

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

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

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

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

Компилируемые языки (например, C, C++)

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


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

Исходная сборка Запустить исполняемый файл Rebuild

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

Это несколько упрощено, так как многие современные программы, созданные с использованием скомпилированных языков, используют динамически подключаемые библиотеки или общие библиотеки. Поэтому для запуска исполняемого файла могут потребоваться эти динамические связанные библиотеки (Windows) или общие библиотеки (Linux, Unix).

Интерпретируемые языки программирования (например, Python, Perl)

Для интерпретируемого языка этот процесс отличается. Вместо перевода исходного кода на машинный язык до создания исполняемого файла интерпретатор преобразует исходный код на машинный язык во время работы программы. Это показано ниже:


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

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

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

А теперь кое-что другое. Java

Язык программирования Java не вписывается ни в модели компилируемого языка, ни в модели интерпретируемого языка. Это показано на рисунке ниже.


Компилятор Java (javac) преобразует исходный код в байт-код. Байт-код — это своего рода средний машинный язык. Этот файл байт-кода (файл .class) можно запустить в любой операционной системе с помощью интерпретатора Java (java) для этой платформы. Интерпретатор называется виртуальной машиной. Таким образом, Java является примером языка программирования для виртуальных машин.

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

Способ, которым языки программирования виртуальных машин получают часть скорости компилируемых языков, заключается в том, что исходный код пропускается через компилятор для создания байт-кода. Это преобразование происходит до запуска программы. Способ, которым языки виртуальных машин достигают своей переносимости (независимости от платформы), заключается в наличии разных интерпретаторов для каждой поддерживаемой операционной системы. Этот интерпретатор связывает правильные библиотеки времени выполнения для каждой операционной системы. Скомпилированный байт-код представляет собой средний машинный язык, который будет работать без изменений с любым интерпретатором виртуальной машины для этого языка. Этот процесс проиллюстрирован далее. У нас есть компилятор, который преобразует исходный код в байт-код. Это можно смоделировать, нажав кнопку Compile. После создания байт-кода этот же байт-код можно использовать без каких-либо изменений в любой операционной системе, имеющей интерпретатор виртуальной машины для языка программирования. Обратите внимание, что каждый из интерпретаторов виртуальных машин имеет разный код библиотеки времени выполнения, поскольку каждая операционная система имеет разные библиотеки времени выполнения. Вот как язык виртуальной машины решает проблемы зависимости от платформы. Нажмите «Запустить Windows», «Запустить Mac OSX» или «Запустить Linux», чтобы имитировать запуск программы в любой из этих операционных систем.

ЭТА СТРАНИЦА СОДЕРЖИТ ПРИМЕРЫ ОТВЕТОВ на викторину по главе 1 этого интерактивного учебника по Java. Обратите внимание, что во многих случаях существует множество правильных ответов на заданный вопрос.

Вопрос 1. Одним из компонентов компьютера является его ЦП. Что такое ЦП и какую роль он играет в компьютере?

Ответ: Центральный процессор или центральный процессор является активной частью компьютера. Его функция заключается в выполнении программ, написанных на машинном языке и хранящихся в основной памяти (ОЗУ) компьютера. Он делает это, повторяя цикл выборки и выполнения снова и снова; то есть он неоднократно извлекает из памяти инструкцию машинного языка и выполняет ее.

Вопрос 2: Объясните, что подразумевается под «асинхронным событием». Приведите несколько примеров.

Ответ: Асинхронное событие — это событие, которое происходит в непредсказуемое время вне контроля программы, которую выполняет ЦП. Он не "синхронизируется" с программой. Например, когда пользователь нажимает клавишу на клавиатуре или щелкает кнопку мыши. (Эти события генерируют «прерывания», которые заставляют ЦП прерывать свою работу и предпринимать некоторые действия для обработки асинхронного события. После обработки события ЦП возвращается к тому, что он делал до того, как оно было прервано.)

Вопрос 3: В чем разница между «компилятором» и «интерпретатором»?

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

Вопрос 4. Объясните разницу между языки высокого уровня и машинный язык.

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

Вопрос 5. Если у вас есть исходный код программы на Java, и вы хотите запустить эту программу, вам потребуются оба символа < i>компилятор и интерпретатор. Что делает компилятор Java и что делает интерпретатор Java?

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

Вопрос 6: Что такое подпрограмма?

< p> Ответ: Подпрограмма — это набор инструкций для выполнения какой-либо задачи, которые были сгруппированы вместе и получили имя. Позже, когда эта задача должна быть выполнена, достаточно вызвать подпрограмму, указав ее имя, а не повторять всю последовательность инструкций.

Вопрос 7: Java — это объектно-ориентированный язык программирования. . Что такое объект?

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

< p> Вопрос 8: Что такое переменная? (Есть четыре разных понятия, связанных с переменными в Java. Постарайтесь упомянуть в своем ответе все четыре аспекта. Подсказка: один из аспектов — это имя переменной. )

Ответ: Переменная — это ячейка памяти, которой присвоено имя, чтобы на нее можно было легко ссылаться в программе. Переменная содержит значение, которое должно быть определенного типа. Значение может быть изменено в процессе выполнения программы.

Вопрос 9: Java является "платформенно-независимым языком". Что это значит?

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

Вопрос 10: Что такое "Интернет"? Приведите несколько примеров его использования. (Какие услуги он предоставляет?)

Ответ: Интернет — это сеть, соединяющая миллионы компьютеров по всему миру. Компьютеры, подключенные к Интернету, могут взаимодействовать друг с другом. Интернет можно использовать для Telnet (который позволяет пользователю одного компьютера удаленно подключаться к другому компьютеру), FTP (который используется для копирования файлов между компьютерами) и World Wide Web (который позволяет просматривать «страницы» информации). опубликовано на компьютерах по всему миру.


Компьютеры — это электронные устройства, способные понимать только двоичный код машинного уровня (0/1 или вкл/выкл), и чрезвычайно сложно понять и написать программу на машинном языке, поэтому разработчики используют удобочитаемый код высокого уровня и Руководство по сборке. Чтобы восполнить этот пробел, используется транслятор, который преобразует инструкции высокого уровня в инструкции машинного уровня (0 и 1).

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

Почему компьютерный переводчик?

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

Назначение переводчика компьютерного языка

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

Типы переводчиков компьютерного языка

  1. Компилятор
  2. Переводчик
  3. Ассемблер

Компилятор

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

В процессе создания исполняемого файла компилятор проходит различные этапы, такие как лексический анализ, синтаксический анализ, семантический анализ, генерация промежуточного представления (IR), (промежуточное представление) IR-оптимизация, генерация кода и оптимизация.

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

Некоторые распространенные компилируемые языки – C++, C

Характеристики компилятора

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

Преимущество компилятора

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

Недостаток компилятора

  • Для создания исполняемого файла исходный код не должен содержать ошибок.

Переводчик

Интерпретатор преобразует язык высокого уровня в язык машинного уровня; компилятор делает то же самое, но по-другому. Во время выполнения исходный код в Interpreter преобразуется в машинный код. Однако перед запуском программы код преобразуется компилятором в машинный код, т. е. в исполняемый файл.

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

Некоторые из популярных интерпретируемых языков: Php, Python, Javascript, Ruby

Характеристики переводчика

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

Ассемблер

Assembler преобразует код, написанный на языке ассемблера, в код машинного уровня. Язык ассемблера содержит мнемоники машинных кодов операций, поэтому ассемблеры переводят мнемоники в прямые инструкции в соотношении 1:1.

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

Характеристики Ассемблера

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

Разница между компилятором, интерпретатором и ассемблером

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

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

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

Часто задаваемые вопросы

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

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

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

Ответ: компиляция происходит перед выполнением в процессе компиляции. Исходный код компилируется и создается исполняемый файл (например, .dll и .exe), и этот файл запускается во время выполнения. Компилятор взаимодействует с диспетчером памяти ОС для выполнения компиляции. Выполнение выполняется процессором во время выполнения программы.

  • Внешний интерфейс
  • Средний конец
  • Верхняя часть

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

8 Что такое общий промежуточный язык (CIL)?

Промежуточным языком в среде Java является байт-код.

9) Является ли Java компилируемым языком?

Ответ: Процесс компиляции Java состоит из двух этапов. Сначала исходный код преобразуется компилятором в байт-код, а во время выполнения этот байт-код проверяется верификатором байтов, и он решает, что может компилировать и/или интерпретировать байт-код с помощью Java Interpreter/JIT Compiler. (источник: StackOverflow)

10) Является ли языковой переводчик системным программным обеспечением?

Ответ: Системное программное обеспечение — это те типы программного обеспечения, которые предназначены для обеспечения платформы для другого программного обеспечения. Это программное обеспечение обеспечивает среду для работы и программирования, в которой пользователи взаимодействуют для создания прикладного программного обеспечения. Это включает в себя операционную систему, переводчик (языковой процессор), симуляторы, эмуляторы, служебное программное обеспечение и т. д. Таким образом, переводчики, такие как компиляторы, переводчики и интерпретаторы, являются системным программным обеспечением.


сообщить об этом объявлении

Читайте также: