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

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

Этот шаг состоит из нескольких процессов и меняет ваш код несколько раз.

(Изображение: https://www3.ntu.edu.sg)

  1. Предварительная обработка. На этом первом этапе ваш код очищается.
  • Он удаляет все свои комментарии (которые на самом деле не заботят вашу машину)
  • И каждый код, начинающийся с #, расширяется или вписывается в код более явно.

Перед предварительной обработкой:

/* Comment */ 
#include <stdio.h>
int main(void)
{  
     printf("hello");
} 

После предварительной обработки:

Code of stdio.h file
int main(void)
{  
     printf("hello");
} 

2. Компилятор:

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

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

push ebp
mov ebp, esp
and esp, -16
sub esp, 16
mov eax, OFFSET
FLAT:.LC0
mov DWORD PTR
[esp], eax
call printf
leave
ret

3. Ассемблер:

На этом этапе ассемблер переводит все на машинный язык, который работает как кодовые инструкции, понятные вашему центральному процессору (ЦП).

После ассемблера:

0010010101001
0110110010101
1100001101010
1001010101011
0000001101101

4. Линкер:

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

Для базовой компиляции C вы можете использовать GCC. Многоязычный компилятор, созданный для проекта GNU, который был запущен в сентябре 1983 года Ричардом М. Столменом для создания полноценной операционной системы со свободным программным обеспечением. Этот компилятор работает с большинством дистрибутивов Linux и имеет несколько опций, очень полезных при компиляции.

Пример:

У нас следующий путь:

/home/vagrant/C_Compile

Затем мы создаем файл «.c» с

touch main.c

В этом файле мы создаем простой код, который печатает «Hello World», мы используем библиотеку stdio и добавляем некоторые комментарии.

#include <stdio.h>
/**
* main - Entry point
*
* Return: Always 0 (Success)
int main(void)
{
printf("Hello World\n");
return (0);
}

Если мы используем компилятор gcc непосредственно с нашим файлом C, мы проходим все шаги, описанные выше, и по умолчанию создается исполняемый файл с именем «a.out».

Если мы запустим файл «a.out», мы получим ожидаемый результат «Hello World».

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

С опцией -E компиляция останавливается после этапа предварительной обработки. Мы также используем опцию -o, чтобы указать один файл, в котором будет сохранен код до этого момента (препроцессор в данном случае).

Мы получаем файл препроцессора, который содержит много сложного кода (в основном связанного с используемой нами библиотекой stdio). Мы можем убедиться, что наши комментарии были удалены, используя команду «tail», которая печатает последние 10 строк кода.

С опцией -S компиляция останавливается перед процессом сборки и сразу после шага компиляции. Файл с расширением «.s» генерируется автоматически, и если мы его распечатаем, то увидим ассемблерный код.

Если мы хотим увидеть, как выглядит наш код непосредственно перед процессом связывания, мы можем использовать опцию -c, которая автоматически создает файл с расширением «.o», и если мы напечатаем, мы получим много символов, которые мы не понимаем. (хотя ваша машина делает).

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