Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции инф.doc
Скачиваний:
2
Добавлен:
05.12.2019
Размер:
1.56 Mб
Скачать

20. Препроцессорные средства

20.1. Стадии и команды препроцессорной обработки

Назначение препроцессора – обработка исходного текста программы до ее компиляции (можно назвать первой фазой компиляции). Инструкции препроцессора называют директивами. Они начинаются с символа #.

На стадии обработки директив препроцессора возможно выполнение следующих действий:

  1. Замена идентификаторов заранее подготовленными последовательностями символов (#define).

  2. Включение в программу текста из указанных файлов (#include).

  3. Исключение из программы отдельных частей (условная компиляция).

  4. Макроподстановка, т. е. замена обозначения параметризируемым текстом.

20.2. Директива #define

Директива #define имеет несколько модификаций. Они предусматривают определение макросов или препроцессорных идентификаторов, каждому из которых ставится в соответствие некоторая последовательность символов. В последующем тексте программы препроцессорные идентификаторы заменяются на заранее оговоренные последовательности символов.

#define идентификатор строка_замещения

Таблица 2. Пример работы директивы define

До обработки

После обработки

#define begin {

#define end }

void main()

begin

операторы

end

void main()

{

операторы

}

С помощью #define удобно определять размеры массивов

Таблица 3. Пример работы директивы define

До обработки

После обработки

#define N 10

#define M 100

void main()

{

int matr[N][N];

double mas[M]

….

}

void main()

{

int matr[10][10];

double mas[100]

}

Те же возможности в С++ обеспечивают константы, определенные в тексте программы. Поэтому в С++ по сравнению с классическим С #define используется реже.

void main() //использование констант в С++

{

const int N=10;

const int M=100;

int matr[N][N];

double mas[M]

}

20.3. Включение текстов из файлов

Для включения текста из файла используется команда #include. Она имеет две формы записи:

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

#include “имя_файла”

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

По принятому соглашению к тем файлам, которые надо помещать в заголовке программы приписывается расширение h (заголовочные файлы).

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

//файл tree. h

//дерево и функции для его формирования и печати

#include <iostream.h>

struct Point

{

int key;

Point*left,*right;

};

Point* first(int d)//формирование первого элемента дерева

{

Point* p=new Point;

p->key=d;

p->left=0;

p->right=0;

return p;

}

Point* Add(Point*root,int d)//добавление элемента d в дерево поиска

{

Point*p=root,*r;

bool ok=false;

while(p&&!ok)

{

r=p;

if(d==p->key)ok=true;

else

if(d<p->key)p=p->left;//пойти в левое поддерево

else p=p->right;//пойти в правое поддерево

}

if(ok) return p;//найдено, не добавляем

//создаем узел

Point* New_point=new Point();//выделили память

New_point->key=d;

New_point->left=0;

New_point->right=0;

if(d<r->key)r->left=New_point;

else r->right =New_point;

return New_point;

}

void Show(Point*p,int level)

{

if(p)

{

Show(p->left,level+5);

for(int i=0;i<level;i++)cout<<" ";

cout<<p->key<<"\n";

Show(p->right,level+5);

}

}

//Файл с основной программой

#include <iostream.h>

#include "tree.h"

void main()

{

int n,k;

cout<<"n?";

cin>>n;

Point *root=first(10);//первый элемент

for(int i=0;i<n;i++)

{

cout<<"?";

cin>>k;

Add(root,k);

}

Show(root,0);

}

Препроцессор добавляет текст файла tree.h в файл, в котором расположена основная программа и как единое целое передает на компиляцию.