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

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

#include ‹stdio.h›

/**
* main — точка входа
*
* Возврат: всегда 0 (успешно)
*/

int main(void)
{
return (0);
}

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

1. Предварительная обработка

На этом этапе читаются команды препроцессора, это строки, начинающиеся с символа «#». В указанном коде одна из этих команд находится в первой строке.

#include ‹stdio.h›

Это команда включения синтаксиса с опцией угловых скобок. Это указывает gcc искать в стандартном списке системных каталогов все, что введено между этими угловыми скобками. Для пользователей Linux это каталог /usr/include.

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

Теперь, когда stdio.h объединен с вашим кодом, в него вносятся некоторые изменения. «stdio.h» проходит через ваш код, удаляя комментарии и беря любые объявления и макросы, которые могли быть использованы, и расширяя их до их полной формы. Запуск gcc -E ‹filename› с вашим кодом создаст файл с суффиксом .i, который более четко иллюстрирует это. Когда-то человекочитаемый код стал менее понятным. Это подготовит файл ко второму шагу процесса компиляции.

2. Компиляция

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

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

3. Сборка

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

4. Связывание

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