Роль препроцессора.

Этапы обработки программы.

Язык Си относится к языкам высокого уровня, т.е. предназначенным для записи программы в форме, удобной для человека и не "привязанной" к конкретному типу машин. Исходный текст программы на Си, введенный с помощью клавиатуры в память компьютера - исходный код (source code, обычно хранится в файлах с расширением *.cpp). Он может быть разбит на смысловые части (функции и т.д.). Если эти части хранятся в разных файлах, то каждый такой файл называется исходным модулем.

Компилятор - программа, осуществляющая перевод программ с языка высокого уровня (приближенного к человеку) на язык более низкого уровня (близкий к ЭВМ), или язык машинных команд. Компиляция программы на языке Си состоит из двух этапов: начальной обработки, выполняемой т.н. препроцессором, и собственно компиляции. Результат обработки исходного модуля компилятором - объектный код (object code, обычно хранится в файлах с расширением *.obj). В большинстве случаев компилятор переводит на машинный язык каждую функцию по отдельности, не связывая их друг с другом и с библиотечными функциями; поэтому объектный код не может еще быть выполнен.

Лишь вторая специальная программа - редактор связей (Linker) - создает исполняемый (абсолютный, загрузочный) код, "связывая" между собой функции и места их использования (вызова), подключая при этом и библиотечные функции. Linker еще называют компоновщиком, т.к. он объединяет программные модули в новый модуль, пригодный для выполнения - загрузочный модуль (Load module, расширение *.exe).

Большинство сред программирования по команде "Запуск программы" ("Run") автоматически выполняют все указанные этапы. Однако знать их различие все же стоит, чтобы при возникновении ошибок лучше понимать их причины. По тексту сообщения об ошибке обычно четко видно, на каком этапе она произошла.

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

Препроцессорные директивы начинаются с символа #, за которым следует наименование директивы, указывающее текущую операцию препроцессора.

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

#include <имя_файла.h>

где «h» – расширение заголовочных файлов.

Если имя файла заключено в угловые скобки (< >), то поиск дан­но­го файла производится в стандартной директории (папке) с этими файлами, если же имя файла заключено в двойные кавычки (” ”), то поиск данного файла производится в текущей директории.

К наиболее часто используемым библиотекам относятся:

stdio.h - содержит стандартные функции файлового ввода-вывода;

conio.h - функции для работы с консолью (клавиатура, экран монитора);

iostream.h - функции потокового ввода-вывода (см. ниже);

math.h - математические функции.

 

Второе основное назначение препроцессора – это обработка макро­­опре­делений. Макроподстановка define (определить) имеет общий вид:

#define < ID > <строка>

Например: #define PI 3.1415927

В ходе препроцессорной обработки программы появление в тексте идентификатора PI везде заменяется значением 3.1415927.

Другие возможности препроцессора будут рассмотрены позже.