Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
С_глава2.doc
Скачиваний:
1
Добавлен:
16.12.2018
Размер:
167.94 Кб
Скачать

Занятие 9. Директивы препроцессора.

При каждом запуске компилятора сначала запускается препроцессор, который ищет команды препроцессора, начинающиеся с символа ‘#’. При выполнении любой из этих команд в текст исходного кода вносятся соответствующие изменения, и создается новый временный файл исходного кода. Директивы препроцессора могут появиться в любом месте исходного кода, но они применимы только к его остатку.

Директива #include

Директива

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

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

Директива #define

Команда #define определяет подстановку в текст программы

#define текстовое_имя текст_подстановки

В тексте исходного файла, следующем за директивой #define, все вхождения текстового_имени заменяются на текст_подстановки. Если текст_подстановки занимает больше, чем одну строку, то его можно продолжить на следующей строке, помещая символ обратной дробной черты перед символом “новая строка”. Текст_подстановки может быть опущен. В этом случае удаляются все вхождения текстового_имени из текста программы. Тем не менее, текстовое_имя считается определенным и принимает значение 1, если проверяется директивой препроцессора #if. Текстовое_имя рекомендуется записывать прописными буквами, чтобы зрительно отличать их от имен переменных и функций. Определение символических констант с помощью директив #define полезно, когда нужно ввести короткое имя для длинной константы, или определить константы, которые могут поменяться в процессе эксплуатации программы.

Примеры.

1) #define PI 3.1415926

#define BIG 512 // лексема BIG в любом месте программы будет заменена строкой 512 int myArray[BIG];

#define VASIA “Василий Иванович”

#define MAX // Текст МАX удаляется из исходного текста программы

Директивы условной компиляции #if, #elif, #else и #endif

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

#if константное_выражение

текст_программы

#elif константное_выражение

текст программы

#elif константное_выражение

текст_программы

#else

текст_программы

#endif

Каждой директиве #if в исходном файле должна соответствовать закрывающая директива #endif. Между директивами #if и #endif могут использоваться директивы #elif и не более одной директивы #else. Директива #else, если она есть, должна быть последней директивой перед директивой #endif.

Препроцессор проверяет каждое константное_выражение, которое следует за директивой #if или #elif, пока не будет найдено выражение со значением истина (не 0). И компилируется текст_программы, следующий за истинным выражением, до соответствующей директивы препроцессора #elif, #else, #endif. Этот текст_программы может содержать другие директивы препроцессора, начинающиеся со знака #.

Если все константные_выражения ложны или отсутствуют директивы #elif, то препроцессор выбирает текст программы после директивы #else. Если к тому же отсутствует и директива #else, то никакой текст не выбирается.

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

1) условное включение различных версий заголовочного файла

#if VERSION == 1

#define INFILE “vers1.h”

#elif VERSION == 2

#define INFILE “vers2.h” // и так далее

#else

#define INFILE “versN.h”

#endif

#include INFILE

2) временно закомментированный фрагмент кода

#if 0

int i, j;

double x, y;

#endif

Наиболее часто в программах используются директивы #ifdef и #ifndef, позволяющие управлять компиляцией в зависимости от того, определен ли с помощью директивы #define указанный в них символ (хотя бы как пустая строка).

Примеры использования директив #ifdef и #ifndef.

1) #ifdef SYMBOL

// Расположенный ниже код до первого elif, #else, или #endif компилируется, если // SYMBOL определен

2) #ifndef SYMBOL

// Расположенный ниже код компилируется, если SYMBOL не определен

3) #ifndef HEADER_INCLUDED // Включение заголовочного myheader.h файла только один раз

#include “myheader.h”

#define HEADER_INCLUDED

#endif

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

#define DEMO

#define NUMBER 5

#include <stdio.h>

int main()

{ puts(“ Проверка определения DEMO\n”);

#ifdef DEMO

puts(“ DEMO – определена”);

#else puts(“ DEMO – не определена\n”);

#endif

#ifndef NUMBER

puts(“ NUMBER – не определена”);

#else

printf(“NUMBER определена как %d\n”,NUMBER);

#endif

}