- •Оглавление
- •Занятие 6. Функции.
- •Прототип функции
- •Определение функции
- •Аргументы и параметры функции
- •Функции с переменным числом параметров
- •Рекурсивные функции
- •Математические функции
- •Передача массивов как параметров
- •Передача многомерных массивов как параметров
- •Использование указателей при работе с функциями
- •Перегрузка функций
- •Занятие 7. Коллоквиум.
- •Занятие 8. Строки Указатели и строки
- •Функции ввода, вывода строк
- •Стандартные функции обработки строк
- •Занятие 9. Директивы препроцессора.
- •Директива #include
- •Директива #define
- •Директивы условной компиляции #if, #elif, #else и #endif
- •Директива #undef
- •Макроопределения с параметрами
- •Занятие 10.
- •Занятие 11.
- •Занятие 12.
Занятие 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
}